Merge m-c to autoland, a=merge

This commit is contained in:
Wes Kocher 2016-09-07 18:07:50 -07:00
commit ac33516b3c
279 changed files with 1644 additions and 4236 deletions

View File

@ -124,7 +124,6 @@ XULTreeAccessible::Value(nsString& aValue)
return;
int32_t currentIndex;
nsCOMPtr<nsIDOMElement> selectItem;
selection->GetCurrentIndex(&currentIndex);
if (currentIndex >= 0) {
nsCOMPtr<nsITreeColumn> keyCol;

View File

@ -403,9 +403,6 @@ pref("dom.phonenumber.substringmatching.VE", 7);
pref("dom.phonenumber.substringmatching.CL", 8);
pref("dom.phonenumber.substringmatching.PE", 7);
// WebAlarms
pref("dom.mozAlarms.enabled", true);
// NetworkStats
#ifdef MOZ_WIDGET_GONK
pref("dom.mozNetworkStats.enabled", true);

View File

@ -7,7 +7,6 @@
window.performance.mark('gecko-shell-loadstart');
Cu.import('resource://gre/modules/ContactService.jsm');
Cu.import('resource://gre/modules/AlarmService.jsm');
Cu.import('resource://gre/modules/NotificationDB.jsm');
Cu.import("resource://gre/modules/AppsUtils.jsm");
Cu.import('resource://gre/modules/UserAgentOverrides.jsm');

View File

@ -170,7 +170,6 @@
#endif
@RESPATH@/components/dom_canvas.xpt
@RESPATH@/components/dom_contacts.xpt
@RESPATH@/components/dom_alarm.xpt
@RESPATH@/components/dom_core.xpt
@RESPATH@/components/dom_css.xpt
@RESPATH@/components/dom_events.xpt
@ -363,8 +362,6 @@
@RESPATH@/components/PermissionSettings.manifest
@RESPATH@/components/PermissionPromptService.js
@RESPATH@/components/PermissionPromptService.manifest
@RESPATH@/components/AlarmsManager.js
@RESPATH@/components/AlarmsManager.manifest
@RESPATH@/components/FeedProcessor.manifest
@RESPATH@/components/FeedProcessor.js
@RESPATH@/components/PackagedAppUtils.manifest

View File

@ -107,6 +107,7 @@ a {
#searchSubmit {
margin-inline-start: -1px;
color: transparent;
background: url("chrome://browser/skin/search-arrow-go.svg#search-arrow-go") center center no-repeat, linear-gradient(hsla(0,0%,100%,.8), hsla(0,0%,100%,.1)) padding-box;
padding: 0;
border: 1px solid;
@ -115,7 +116,6 @@ a {
border-inline-start: 1px solid transparent;
box-shadow: 0 0 2px hsla(0,0%,100%,.5) inset,
0 1px 0 hsla(0,0%,100%,.2);
color: inherit;
cursor: pointer;
transition-property: background-color, border-color, box-shadow;
transition-duration: 150ms;
@ -132,7 +132,6 @@ a {
#searchText + #searchSubmit:hover,
#searchText[autofocus] + #searchSubmit {
border-color: #59b5fc #45a3e7 #3294d5;
color: white;
}
#searchText:focus + #searchSubmit,

View File

@ -44,8 +44,8 @@
<input type="text" name="q" value="" id="searchText" maxlength="256"
aria-label="&contentSearchInput.label;" autofocus="autofocus"
dir="auto"/>
<input id="searchSubmit" type="button" value="" onclick="onSearchSubmit(event)"
aria-label="&contentSearchSubmit.label;"/>
<input id="searchSubmit" type="button" value="&#x25b6;" onclick="onSearchSubmit(event)"
title="&contentSearchSubmit.tooltip;"/>
</div>
<div id="snippetContainer">

View File

@ -399,6 +399,7 @@ input[type=button] {
#newtab-search-submit {
margin-inline-start: -1px;
color: transparent;
background: url("chrome://browser/skin/search-arrow-go.svg#search-arrow-go") center center no-repeat, linear-gradient(hsla(0,0%,100%,.8), hsla(0,0%,100%,.1)) padding-box;
padding: 0;
border: 1px solid;
@ -407,7 +408,6 @@ input[type=button] {
border-inline-start: 1px solid transparent;
box-shadow: 0 0 2px hsla(0,0%,100%,.5) inset,
0 1px 0 hsla(0,0%,100%,.2);
color: inherit;
cursor: pointer;
transition-property: background-color, border-color, box-shadow;
transition-duration: 150ms;
@ -423,7 +423,6 @@ input[type=button] {
#newtab-search-text + #newtab-search-submit:hover,
#newtab-search-text[autofocus] + #newtab-search-submit {
border-color: #59b5fc #45a3e7 #3294d5;
color: white;
}
#newtab-search-text:focus + #newtab-search-submit,

View File

@ -71,8 +71,8 @@
<div id="newtab-search-icon"/>
<input type="text" name="q" value="" id="newtab-search-text"
aria-label="&contentSearchInput.label;" maxlength="256" dir="auto"/>
<input id="newtab-search-submit" type="button" value=""
aria-label="&contentSearchSubmit.label;"/>
<input id="newtab-search-submit" type="button" value="&#x25b6;"
title="&contentSearchSubmit.tooltip;"/>
</div>
</div>

View File

@ -2635,45 +2635,6 @@ ContentPermissionPrompt.prototype = {
"geo-notification-icon", options);
},
_promptFlyWebPublishServer : function(aRequest) {
var message = "Would you like to let this site start a server accessible to nearby devices and people?";
var actions = [
{
stringId: "flyWebPublishServer.allowPublishServer",
action: Ci.nsIPermissionManager.ALLOW_ACTION,
expireType: Ci.nsIPermissionManager.EXPIRE_SESSION
},
{
stringId: "flyWebPublishServer.denyPublishServer",
action: Ci.nsIPermissionManager.DENY_ACTION,
expireType: Ci.nsIPermissionManager.EXPIRE_SESSION
}
];
let options = {
learnMoreURL: "https://flyweb.github.io",
popupIconURL: "chrome://flyweb/skin/icon-64.png"
};
let browser = this._getBrowserForRequest(aRequest);
let chromeDoc = browser.ownerDocument;
let iconElem = chromeDoc.getElementById("flyweb-publish-server-notification-icon");
if (!iconElem) {
let notificationPopupBox = chromeDoc.getElementById("notification-popup-box");
let notificationIcon = chromeDoc.createElement("image");
notificationIcon.setAttribute("id", "flyweb-publish-server-notification-icon");
notificationIcon.setAttribute("src", "chrome://flyweb/skin/icon-64.png");
notificationIcon.setAttribute("class", "notification-anchor-icon flyweb-publish-server-icon");
notificationIcon.setAttribute("style", "filter: url(chrome://browser/skin/filters.svg#fill); fill: currentColor; opacity: .4;");
notificationIcon.setAttribute("role", "button");
notificationIcon.setAttribute("aria-label", "View the publish-server request");
notificationPopupBox.appendChild(notificationIcon);
}
this._showPrompt(aRequest, message, "flyweb-publish-server", actions, "flyweb-publish-server",
"flyweb-publish-server-notification-icon", options);
},
_promptWebNotifications : function(aRequest) {
var message = gBrowserBundle.GetStringFromName("webNotifications.receiveFromSite");
@ -2738,8 +2699,7 @@ ContentPermissionPrompt.prototype = {
let perm = types.queryElementAt(0, Ci.nsIContentPermissionType);
const kFeatureKeys = { "geolocation" : "geo",
"desktop-notification" : "desktop-notification",
"flyweb-publish-server": "flyweb-publish-server"
"desktop-notification" : "desktop-notification"
};
// Make sure that we support the request.
@ -2782,11 +2742,6 @@ ContentPermissionPrompt.prototype = {
case "desktop-notification":
this._promptWebNotifications(request);
break;
case "flyweb-publish-server":
if (AppConstants.NIGHTLY_BUILD) {
this._promptFlyWebPublishServer(request);
}
break;
}
},

View File

@ -16,9 +16,9 @@
"unpack": true
},
{
"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
"size": 131489924,
"digest": "59f7463a0da38f324daa4ffc2678d78afb4fe0df13248c1d215bcb996ec05e8521155563cde9a8b719a9b98c5feeaf97cc9e8d52c9b95f6b44728870d908d5b6",
"version": "gecko rustc 1.11.0 (9b21dcd6a 2016-08-15) x86_64+i586",
"size": 99378568,
"digest": "ea5ae0a37ab8c583ef3f9a97c45baf0644feed95f1e6191a4456fd42bbd45b218fe4bc528747a63af55ce67c4b6155bd50f312746628b30e41c421f4d54e5417",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true

View File

@ -190,7 +190,6 @@
@RESPATH@/components/dom_bluetooth.xpt
#endif
@RESPATH@/components/dom_canvas.xpt
@RESPATH@/components/dom_alarm.xpt
@RESPATH@/components/dom_core.xpt
@RESPATH@/components/dom_css.xpt
@RESPATH@/components/dom_events.xpt
@ -531,8 +530,6 @@
@RESPATH@/components/PhoneNumberService.manifest
@RESPATH@/components/NotificationStorage.js
@RESPATH@/components/NotificationStorage.manifest
@RESPATH@/components/AlarmsManager.js
@RESPATH@/components/AlarmsManager.manifest
@RESPATH@/components/Push.js
@RESPATH@/components/Push.manifest
@RESPATH@/components/PushComponents.js

View File

@ -427,11 +427,11 @@ These should match what Safari and other Apple applications use on OS X Lion. --
<!ENTITY searchFocus.commandkey2 "e">
<!ENTITY searchFocusUnix.commandkey "j">
<!-- LOCALIZATION NOTE (contentSearchInput.label, contentSearchSubmit.label):
These are set as the aria-label attribute for the search input box and
submit button in the in-content search UI, to be used by screen readers. -->
<!-- LOCALIZATION NOTE (contentSearchInput.label):
This is set as the aria-label attribute for the search input box in the
in-content search UI, to be used by screen readers. -->
<!ENTITY contentSearchInput.label "Search query">
<!ENTITY contentSearchSubmit.label "Submit search">
<!ENTITY contentSearchSubmit.tooltip "Submit search">
<!-- LOCALIZATION NOTE (searchFor.label, searchWith.label):
These two strings are used to build the header above the list of one-click

View File

@ -378,16 +378,6 @@ geolocation.neverShareLocation.accesskey=N
geolocation.shareWithSite2=Would you like to share your location with this site?
geolocation.shareWithFile2=Would you like to share your location with this file?
# FlyWeb UI
# LOCALIZATION NOTE (flyWebPublishServer.allowPublishServer): This is an experimental feature only shipping in Nightly, and doesn't need translation.
flyWebPublishServer.allowPublishServer=Allow Server
# LOCALIZATION NOTE (flyWebPublishServer.allowPublishServer.accessKey): This is an experimental feature only shipping in Nightly, and doesn't need translation.
flyWebPublishServer.allowPublishServer.accesskey=A
# LOCALIZATION NOTE (flyWebPublishServer.denyPublishServer): This is an experimental feature only shipping in Nightly, and doesn't need translation.
flyWebPublishServer.denyPublishServer=Block Server
# LOCALIZATION NOTE (flyWebPublishServer.denyPublishServer.accessKey): This is an experimental feature only shipping in Nightly, and doesn't need translation.
flyWebPublishServer.denyPublishServer.accesskey=B
webNotifications.receiveForSession=Receive for this session
webNotifications.receiveForSession.accesskey=s
webNotifications.alwaysReceive=Always Receive Notifications

View File

@ -1711,58 +1711,6 @@ toolbarbutton.chevron > .toolbarbutton-icon {
margin: 0;
}
/* Ctrl-Tab */
#ctrlTab-panel {
-moz-appearance: none;
background: hsla(0,0%,33%,.85);
color: white;
border-style: none;
padding: 20px 10px 10px;
font-weight: bold;
text-shadow: 0 0 1px hsl(0,0%,12%), 0 0 2px hsl(0,0%,12%);
}
.ctrlTab-favicon[src] {
background-color: white;
width: 20px;
height: 20px;
padding: 2px;
}
.ctrlTab-preview-inner > .tabPreview-canvas {
box-shadow: 1px 1px 2px hsl(0,0%,12%);
}
.ctrlTab-preview:not(#ctrlTab-showAll) > * > .ctrlTab-preview-inner > .tabPreview-canvas {
margin-bottom: 2px;
}
.ctrlTab-preview-inner {
padding: 8px;
border: 2px solid transparent;
border-radius: .5em;
}
.ctrlTab-preview:not(#ctrlTab-showAll) > * > .ctrlTab-preview-inner {
margin: -10px -10px 0;
}
#ctrlTab-showAll:not(:focus) > * > .ctrlTab-preview-inner {
background-color: rgba(255,255,255,.2);
}
.ctrlTab-preview:focus > * > .ctrlTab-preview-inner {
color: white;
background-color: rgba(0,0,0,.6);
text-shadow: none;
border-color: white;
}
#ctrlTab-showAll {
margin-top: .5em;
}
/* Status panel */
.statuspanel-label {
@ -1790,9 +1738,9 @@ toolbarbutton.chevron > .toolbarbutton-icon {
}
%include ../shared/fullscreen/warning.inc.css
%include ../shared/ctrlTab.inc.css
%include ../../../devtools/client/themes/responsivedesign.inc.css
%include ../../../devtools/client/themes/commandline.inc.css
%include ../shared/plugin-doorhanger.inc.css
notification.pluginVulnerable > .notification-inner > .messageCloseButton:not(:hover) {

View File

@ -3123,58 +3123,6 @@ menulist.translate-infobar-element > .menulist-dropmarker {
font-weight: bold;
}
/* Ctrl-Tab */
#ctrlTab-panel {
-moz-appearance: none;
-moz-window-shadow: none;
background: hsla(0,0%,33%,.85);
color: white;
border-style: none;
padding: 20px 10px 10px;
text-shadow: 0 0 1px hsl(0,0%,12%), 0 0 2px hsl(0,0%,12%);
}
.ctrlTab-favicon[src] {
background-color: white;
width: 20px;
height: 20px;
padding: 2px;
}
.ctrlTab-preview-inner > .tabPreview-canvas {
box-shadow: 1px 1px 2px hsl(0,0%,12%);
}
.ctrlTab-preview:not(#ctrlTab-showAll) > * > .ctrlTab-preview-inner > .tabPreview-canvas {
margin-bottom: 2px;
}
.ctrlTab-preview-inner {
padding: 8px;
border: 2px solid transparent;
border-radius: .5em;
}
.ctrlTab-preview:not(#ctrlTab-showAll) > * > .ctrlTab-preview-inner {
margin: -10px -10px 0;
}
#ctrlTab-showAll:not(:focus) > * > .ctrlTab-preview-inner {
background-color: rgba(255,255,255,.2);
}
.ctrlTab-preview:focus > * > .ctrlTab-preview-inner {
color: white;
background-color: rgba(0,0,0,.6);
text-shadow: none;
border-color: white;
}
#ctrlTab-showAll {
margin-top: .5em;
}
/* Status panel */
.statuspanel-label {
@ -3202,6 +3150,7 @@ menulist.translate-infobar-element > .menulist-dropmarker {
}
%include ../shared/fullscreen/warning.inc.css
%include ../shared/ctrlTab.inc.css
%include ../../../devtools/client/themes/responsivedesign.inc.css
%include ../../../devtools/client/themes/commandline.inc.css
%include ../shared/plugin-doorhanger.inc.css

View File

@ -0,0 +1,63 @@
%if 0
/* 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/. */
%endif
/* Ctrl-Tab */
#ctrlTab-panel {
-moz-appearance: none;
%ifdef XP_MACOSX
-moz-window-shadow: none;
%endif
background: hsla(0,0%,33%,.85);
color: white;
border-style: none;
padding: 20px 10px 10px;
%ifndef XP_MACOSX
font-weight: bold;
%endif
text-shadow: 0 0 1px hsl(0,0%,12%), 0 0 2px hsl(0,0%,12%);
}
.ctrlTab-favicon[src] {
background-color: white;
width: 20px;
height: 20px;
padding: 2px;
}
.ctrlTab-preview-inner > .tabPreview-canvas {
box-shadow: 1px 1px 2px hsl(0,0%,12%);
}
.ctrlTab-preview:not(#ctrlTab-showAll) > * > .ctrlTab-preview-inner > .tabPreview-canvas {
margin-bottom: 2px;
}
.ctrlTab-preview-inner {
padding: 8px;
border: 2px solid transparent;
border-radius: .5em;
}
.ctrlTab-preview:not(#ctrlTab-showAll) > * > .ctrlTab-preview-inner {
margin: -10px -10px 0;
}
#ctrlTab-showAll:not(:focus) > * > .ctrlTab-preview-inner {
background-color: rgba(255,255,255,.2);
}
.ctrlTab-preview:focus > * > .ctrlTab-preview-inner {
color: white;
background-color: rgba(0,0,0,.6);
text-shadow: none;
border-color: white;
}
#ctrlTab-showAll {
margin-top: .5em;
}

View File

@ -2393,58 +2393,6 @@ notification[value="translation"] {
-moz-image-region: auto;
}
/* Ctrl-Tab */
#ctrlTab-panel {
-moz-appearance: none;
background: hsla(0,0%,33%,.85);
color: white;
border-style: none;
padding: 20px 10px 10px;
font-weight: bold;
text-shadow: 0 0 1px hsl(0,0%,12%), 0 0 2px hsl(0,0%,12%);
}
.ctrlTab-favicon[src] {
background-color: white;
width: 20px;
height: 20px;
padding: 2px;
}
.ctrlTab-preview-inner > .tabPreview-canvas {
box-shadow: 1px 1px 2px hsl(0,0%,12%);
}
.ctrlTab-preview:not(#ctrlTab-showAll) > * > .ctrlTab-preview-inner > .tabPreview-canvas {
margin-bottom: 2px;
}
.ctrlTab-preview-inner {
padding: 8px;
border: 2px solid transparent;
border-radius: .5em;
}
.ctrlTab-preview:not(#ctrlTab-showAll) > * > .ctrlTab-preview-inner {
margin: -10px -10px 0;
}
#ctrlTab-showAll:not(:focus) > * > .ctrlTab-preview-inner {
background-color: rgba(255,255,255,.2);
}
.ctrlTab-preview:focus > * > .ctrlTab-preview-inner {
color: white;
background-color: rgba(0,0,0,.6);
text-shadow: none;
border-color: white;
}
#ctrlTab-showAll {
margin-top: .5em;
}
/* Status panel */
.statuspanel-label {
@ -2484,9 +2432,9 @@ notification[value="translation"] {
}
%include ../shared/fullscreen/warning.inc.css
%include ../shared/ctrlTab.inc.css
%include ../../../devtools/client/themes/responsivedesign.inc.css
%include ../../../devtools/client/themes/commandline.inc.css
%include ../shared/plugin-doorhanger.inc.css
notification.pluginVulnerable > .notification-inner > .messageCloseButton {

View File

@ -158,6 +158,11 @@ private:
virtual void run(const MatchFinder::MatchResult &Result);
};
class KungFuDeathGripChecker : public MatchFinder::MatchCallback {
public:
virtual void run(const MatchFinder::MatchResult &Result);
};
ScopeChecker Scope;
ArithmeticArgChecker ArithmeticArg;
TrivialCtorDtorChecker TrivialCtorDtor;
@ -174,6 +179,7 @@ private:
NoExplicitMoveConstructorChecker NoExplicitMoveConstructor;
RefCountedCopyConstructorChecker RefCountedCopyConstructor;
AssertAssignmentChecker AssertAttribution;
KungFuDeathGripChecker KungFuDeathGrip;
MatchFinder AstMatcher;
};
@ -314,6 +320,44 @@ template<typename T>
StringRef getNameChecked(const T& D) {
return D->getIdentifier() ? D->getName() : "";
}
bool typeIsRefPtr(QualType Q) {
CXXRecordDecl *D = Q->getAsCXXRecordDecl();
if (!D || !D->getIdentifier()) {
return false;
}
StringRef name = D->getName();
if (name == "RefPtr" || name == "nsCOMPtr") {
return true;
}
return false;
}
// The method defined in clang for ignoring implicit nodes doesn't work with
// some AST trees. To get around this, we define our own implementation of
// IgnoreImplicit.
const Stmt *IgnoreImplicit(const Stmt *s) {
while (true) {
if (auto *ewc = dyn_cast<ExprWithCleanups>(s)) {
s = ewc->getSubExpr();
} else if (auto *mte = dyn_cast<MaterializeTemporaryExpr>(s)) {
s = mte->GetTemporaryExpr();
} else if (auto *bte = dyn_cast<CXXBindTemporaryExpr>(s)) {
s = bte->getSubExpr();
} else if (auto *ice = dyn_cast<ImplicitCastExpr>(s)) {
s = ice->getSubExpr();
} else {
break;
}
}
return s;
}
const Expr *IgnoreImplicit(const Expr *e) {
return cast<Expr>(IgnoreImplicit(static_cast<const Stmt *>(e)));
}
}
class CustomTypeAnnotation {
@ -821,6 +865,9 @@ AST_MATCHER(CXXRecordDecl, isLambdaDecl) {
return Node.isLambda();
}
AST_MATCHER(QualType, isRefPtr) {
return typeIsRefPtr(Node);
}
}
}
@ -1145,6 +1192,9 @@ DiagnosticsMatcher::DiagnosticsMatcher() {
AstMatcher.addMatcher(
callExpr(isAssertAssignmentTestFunc()).bind("funcCall"),
&AssertAttribution);
AstMatcher.addMatcher(varDecl(hasType(isRefPtr())).bind("decl"),
&KungFuDeathGrip);
}
// These enum variants determine whether an allocation has occured in the code.
@ -1693,6 +1743,97 @@ void DiagnosticsMatcher::AssertAssignmentChecker::run(
}
}
void DiagnosticsMatcher::KungFuDeathGripChecker::run(
const MatchFinder::MatchResult &Result) {
DiagnosticsEngine &Diag = Result.Context->getDiagnostics();
unsigned ErrorID = Diag.getDiagnosticIDs()->getCustomDiagID(
DiagnosticIDs::Error,
"Unused \"kungFuDeathGrip\" %0 objects constructed from %1 are prohibited");
unsigned NoteID = Diag.getDiagnosticIDs()->getCustomDiagID(
DiagnosticIDs::Note,
"Please switch all accesses to this %0 to go through '%1', or explicitly pass '%1' to `mozilla::Unused`");
const VarDecl *D = Result.Nodes.getNodeAs<VarDecl>("decl");
if (D->isReferenced() || !D->hasLocalStorage() || !D->hasInit()) {
return;
}
// Not interested in parameters.
if (isa<ImplicitParamDecl>(D) || isa<ParmVarDecl>(D)) {
return;
}
const Expr *E = IgnoreImplicit(D->getInit());
const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E);
if (CE && CE->getNumArgs() == 0) {
// We don't report an error when we construct and don't use a nsCOMPtr /
// nsRefPtr with no arguments. We don't report it because the error is not
// related to the current check. In the future it may be reported through a
// more generic mechanism.
return;
}
// We don't want to look at the single argument conversion constructors
// which are inbetween the declaration and the actual object which we are
// assigning into the nsCOMPtr/RefPtr. To do this, we repeatedly
// IgnoreImplicit, then look at the expression. If it is one of these
// conversion constructors, we ignore it and continue to dig.
while ((CE = dyn_cast<CXXConstructExpr>(E)) && CE->getNumArgs() == 1) {
E = IgnoreImplicit(CE->getArg(0));
}
// We allow taking a kungFuDeathGrip of `this` because it cannot change
// beneath us, so calling directly through `this` is OK. This is the same
// for local variable declarations.
//
// We also don't complain about unused RefPtrs which are constructed from
// the return value of a new expression, as these are required in order to
// immediately destroy the value created (which was presumably created for
// its side effects), and are not used as a death grip.
if (isa<CXXThisExpr>(E) || isa<DeclRefExpr>(E) || isa<CXXNewExpr>(E)) {
return;
}
// These types are assigned into nsCOMPtr and RefPtr for their side effects,
// and not as a kungFuDeathGrip. We don't want to consider RefPtr and nsCOMPtr
// types which are initialized with these types as errors.
const TagDecl *TD = E->getType()->getAsTagDecl();
if (TD && TD->getIdentifier()) {
static const char *IgnoreTypes[] = {
"already_AddRefed",
"nsGetServiceByCID",
"nsGetServiceByCIDWithError",
"nsGetServiceByContractID",
"nsGetServiceByContractIDWithError",
"nsCreateInstanceByCID",
"nsCreateInstanceByContractID",
"nsCreateInstanceFromFactory",
};
for (uint32_t i = 0; i < sizeof(IgnoreTypes) / sizeof(IgnoreTypes[0]); ++i) {
if (TD->getName() == IgnoreTypes[i]) {
return;
}
}
}
// Report the error
const char *ErrThing;
const char *NoteThing;
if (isa<MemberExpr>(E)) {
ErrThing = "members";
NoteThing = "member";
} else {
ErrThing = "temporary values";
NoteThing = "value";
}
// We cannot provide the note if we don't have an initializer
Diag.Report(D->getLocStart(), ErrorID) << D->getType() << ErrThing;
Diag.Report(E->getLocStart(), NoteID) << NoteThing << getNameChecked(D);
}
class MozCheckAction : public PluginASTAction {
public:
ASTConsumerPtr CreateASTConsumer(CompilerInstance &CI,

View File

@ -0,0 +1,107 @@
#define MOZ_IMPLICIT __attribute__((annotate("moz_implicit")))
template <typename T>
class already_AddRefed {
public:
already_AddRefed();
T* mPtr;
};
template <typename T>
class RefPtr {
public:
RefPtr();
MOZ_IMPLICIT RefPtr(T* aIn);
MOZ_IMPLICIT RefPtr(already_AddRefed<T> aIn);
~RefPtr();
T* mPtr;
};
template <typename T>
class nsCOMPtr {
public:
nsCOMPtr();
MOZ_IMPLICIT nsCOMPtr(T* aIn);
MOZ_IMPLICIT nsCOMPtr(already_AddRefed<T> aIn);
~nsCOMPtr();
T* mPtr;
};
class Type {
public:
static nsCOMPtr<Type> someStaticCOMPtr;
void f(nsCOMPtr<Type> ignoredArgument, Type *param) {
nsCOMPtr<Type> never_referenced;
nsCOMPtr<Type> kfdg_t1(this);
nsCOMPtr<Type> kfdg_t2 = this;
nsCOMPtr<Type> kfdg_m1(p); // expected-error {{Unused "kungFuDeathGrip" 'nsCOMPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m1', or explicitly pass 'kfdg_m1' to `mozilla::Unused`}}
nsCOMPtr<Type> kfdg_m2 = p; // expected-error {{Unused "kungFuDeathGrip" 'nsCOMPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m2', or explicitly pass 'kfdg_m2' to `mozilla::Unused`}}
nsCOMPtr<Type> kfdg_m3(p);
kfdg_m3.mPtr->f(nullptr, nullptr);
nsCOMPtr<Type> kfdg_m4 = p;
kfdg_m4.mPtr->f(nullptr, nullptr);
nsCOMPtr<Type> kfdg_a1((already_AddRefed<Type>()));
nsCOMPtr<Type> kfdg_a2 = already_AddRefed<Type>();
nsCOMPtr<Type> kfdg_p1(param);
nsCOMPtr<Type> kfdg_p2 = param;
RefPtr<Type> never_referenced2;
RefPtr<Type> kfdg_t3(this);
RefPtr<Type> kfdg_t4 = this;
RefPtr<Type> kfdg_m5(p); // expected-error {{Unused "kungFuDeathGrip" 'RefPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m5', or explicitly pass 'kfdg_m5' to `mozilla::Unused`}}
RefPtr<Type> kfdg_m6 = p; // expected-error {{Unused "kungFuDeathGrip" 'RefPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m6', or explicitly pass 'kfdg_m6' to `mozilla::Unused`}}
RefPtr<Type> kfdg_m7(p);
kfdg_m7.mPtr->f(nullptr, nullptr);
RefPtr<Type> kfdg_m8 = p;
kfdg_m8.mPtr->f(nullptr, nullptr);
RefPtr<Type> kfdg_a3((already_AddRefed<Type>()));
RefPtr<Type> kfdg_a4 = already_AddRefed<Type>();
RefPtr<Type> kfdg_p3(param);
RefPtr<Type> kfdg_p4 = param;
}
Type *p;
};
void f(nsCOMPtr<Type> ignoredArgument, Type *param) {
nsCOMPtr<Type> never_referenced;
Type t;
// Type *p = nullptr;
nsCOMPtr<Type> kfdg_m1(t.p); // expected-error {{Unused "kungFuDeathGrip" 'nsCOMPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m1', or explicitly pass 'kfdg_m1' to `mozilla::Unused`}}
nsCOMPtr<Type> kfdg_m2 = t.p; // expected-error {{Unused "kungFuDeathGrip" 'nsCOMPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m2', or explicitly pass 'kfdg_m2' to `mozilla::Unused`}}
nsCOMPtr<Type> kfdg_m3(t.p);
kfdg_m3.mPtr->f(nullptr, nullptr);
nsCOMPtr<Type> kfdg_m4 = t.p;
kfdg_m4.mPtr->f(nullptr, nullptr);
nsCOMPtr<Type> kfdg_a1((already_AddRefed<Type>()));
nsCOMPtr<Type> kfdg_a2 = already_AddRefed<Type>();
nsCOMPtr<Type> kfdg_p1(param);
nsCOMPtr<Type> kfdg_p2 = param;
RefPtr<Type> never_referenced2;
RefPtr<Type> kfdg_m5(t.p); // expected-error {{Unused "kungFuDeathGrip" 'RefPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m5', or explicitly pass 'kfdg_m5' to `mozilla::Unused`}}
RefPtr<Type> kfdg_m6 = t.p; // expected-error {{Unused "kungFuDeathGrip" 'RefPtr<Type>' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m6', or explicitly pass 'kfdg_m6' to `mozilla::Unused`}}
RefPtr<Type> kfdg_m7(t.p);
kfdg_m7.mPtr->f(nullptr, nullptr);
RefPtr<Type> kfdg_m8 = t.p;
kfdg_m8.mPtr->f(nullptr, nullptr);
RefPtr<Type> kfdg_a3((already_AddRefed<Type>()));
RefPtr<Type> kfdg_a4 = already_AddRefed<Type>();
RefPtr<Type> kfdg_p3(param);
RefPtr<Type> kfdg_p4 = param;
}
nsCOMPtr<Type> Type::someStaticCOMPtr(nullptr);

View File

@ -15,6 +15,7 @@ SOURCES += [
'TestGlobalClass.cpp',
'TestHeapClass.cpp',
'TestInheritTypeAnnotationsFromTemplateArgs.cpp',
'TestKungFuDeathGrip.cpp',
'TestMultipleAnnotations.cpp',
'TestMustOverride.cpp',
'TestMustUse.cpp',

View File

@ -105,7 +105,7 @@ def rust_target(rust_compiler, rustc, target, cross_compiling):
# OpenBSD
('x86_64', 'OpenBSD'): 'x86_64-unknown-openbsd',
# Linux
('x86', 'Linux'): 'i686-unknown-linux-gnu',
('x86', 'Linux'): 'i586-unknown-linux-gnu',
# Linux
('x86_64', 'Linux'): 'x86_64-unknown-linux-gnu',
# OS X and iOS

View File

@ -76,6 +76,10 @@ leak:processInternalEntity
# Bug 1187421 - With e10s, NSS does not always free the error stack. m1.
leak:nss_ClearErrorStack
# Bug 1189430 - DNS leaks in mochitest-chrome.
leak:nsDNSService::AsyncResolveExtended
leak:_GetAddrInfo_Portable
# Bug 1189568 - Indirect leaks of IMContextWrapper and nsIntRect.
leak:nsWindow::Create
leak:nsBaseWidget::StoreWindowClipRegion

View File

@ -141,8 +141,6 @@ CopyURIs(const InfallibleTArray<URIParams>& aDomains, nsIDomainSet* aSet)
void
DomainPolicy::ApplyClone(DomainPolicyClone* aClone)
{
nsCOMPtr<nsIDomainSet> list;
CopyURIs(aClone->blacklist(), mBlacklist);
CopyURIs(aClone->whitelist(), mWhitelist);
CopyURIs(aClone->superBlacklist(), mSuperBlacklist);

View File

@ -75,7 +75,6 @@ nsChromeRegistryContent::RegisterPackage(const ChromePackage& aPackage)
return;
}
if (aPackage.skinBaseURI.spec.Length()) {
nsCOMPtr<nsIURI> skinBaseURI;
nsresult rv = NS_NewURI(getter_AddRefs(skin),
aPackage.skinBaseURI.spec,
aPackage.skinBaseURI.charset.get(),

View File

@ -1654,14 +1654,14 @@ nsDocShell::FirePageHideNotification(bool aIsUnload)
if (mContentViewer && !mFiredUnloadEvent) {
// Keep an explicit reference since calling PageHide could release
// mContentViewer
nsCOMPtr<nsIContentViewer> kungFuDeathGrip(mContentViewer);
nsCOMPtr<nsIContentViewer> contentViewer(mContentViewer);
mFiredUnloadEvent = true;
if (mTiming) {
mTiming->NotifyUnloadEventStart();
}
mContentViewer->PageHide(aIsUnload);
contentViewer->PageHide(aIsUnload);
if (mTiming) {
mTiming->NotifyUnloadEventEnd();
@ -7590,6 +7590,7 @@ nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
// nsDocShell::EndPageLoad will clear mLSHE, but we may need this history
// entry further down in this method.
nsCOMPtr<nsISHEntry> loadingSHE = mLSHE;
mozilla::Unused << loadingSHE; // XXX: Not sure if we need this anymore
//
// one of many safeguards that prevent death and destruction if
@ -9331,23 +9332,23 @@ nsDocShell::SetupNewViewer(nsIContentViewer* aNewViewer)
nscolor bgcolor = NS_RGBA(0, 0, 0, 0);
// Ensure that the content viewer is destroyed *after* the GC - bug 71515
nsCOMPtr<nsIContentViewer> kungfuDeathGrip = mContentViewer;
if (mContentViewer) {
nsCOMPtr<nsIContentViewer> contentViewer = mContentViewer;
if (contentViewer) {
// Stop any activity that may be happening in the old document before
// releasing it...
mContentViewer->Stop();
contentViewer->Stop();
// Try to extract the canvas background color from the old
// presentation shell, so we can use it for the next document.
nsCOMPtr<nsIPresShell> shell;
mContentViewer->GetPresShell(getter_AddRefs(shell));
contentViewer->GetPresShell(getter_AddRefs(shell));
if (shell) {
bgcolor = shell->GetCanvasBackground();
}
mContentViewer->Close(mSavingOldViewer ? mOSHE.get() : nullptr);
aNewViewer->SetPreviousViewer(mContentViewer);
contentViewer->Close(mSavingOldViewer ? mOSHE.get() : nullptr);
aNewViewer->SetPreviousViewer(contentViewer);
}
if (mOSHE && (!mContentViewer || !mSavingOldViewer)) {
// We don't plan to save a viewer in mOSHE; tell it to drop
@ -9768,13 +9769,14 @@ nsDocShell::InternalLoad(nsIURI* aURI,
isJavaScript = false;
}
RefPtr<nsGlobalWindow> scriptGlobal = mScriptGlobal;
// First, notify any nsIContentPolicy listeners about the document load.
// Only abort the load if a content policy listener explicitly vetos it!
// Use nsPIDOMWindow since we _want_ to cross the chrome boundary if needed
nsCOMPtr<Element> requestingElement =
mScriptGlobal->AsOuter()->GetFrameElementInternal();
scriptGlobal->AsOuter()->GetFrameElementInternal();
RefPtr<nsGlobalWindow> MMADeathGrip = mScriptGlobal;
int16_t shouldLoad = nsIContentPolicy::ACCEPT;
uint32_t contentType;
@ -9820,7 +9822,7 @@ nsDocShell::InternalLoad(nsIURI* aURI,
nsISupports* context = requestingElement;
if (!context) {
context = ToSupports(mScriptGlobal);
context = ToSupports(scriptGlobal);
}
// XXXbz would be nice to know the loading principal here... but we don't
@ -10326,8 +10328,8 @@ nsDocShell::InternalLoad(nsIURI* aURI,
// applies to aURI.
CopyFavicon(currentURI, aURI, doc->NodePrincipal(), UsePrivateBrowsing());
RefPtr<nsGlobalWindow> win = mScriptGlobal ?
mScriptGlobal->GetCurrentInnerWindowInternal() : nullptr;
RefPtr<nsGlobalWindow> win = scriptGlobal ?
scriptGlobal->GetCurrentInnerWindowInternal() : nullptr;
// ScrollToAnchor doesn't necessarily cause us to scroll the window;
// the function decides whether a scroll is appropriate based on the

View File

@ -1584,7 +1584,6 @@ nsSHistory::LoadEntry(int32_t aIndex, long aLoadType, uint32_t aHistCmd)
return NS_OK; // XXX Maybe I can return some other error code?
}
nsCOMPtr<nsIURI> nexturi;
int32_t pCount = 0;
int32_t nCount = 0;
nsCOMPtr<nsISHContainer> prevAsContainer(do_QueryInterface(prevEntry));
@ -1594,7 +1593,6 @@ nsSHistory::LoadEntry(int32_t aIndex, long aLoadType, uint32_t aHistCmd)
nextAsContainer->GetChildCount(&nCount);
}
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
if (mRequestedIndex == mIndex) {
// Possibly a reload case
docShell = mRootDocShell;

View File

@ -1,140 +0,0 @@
/* 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/. */
"use strict";
this.EXPORTED_SYMBOLS = ["AlarmDB"];
/* static functions */
const DEBUG = false;
function debug(aStr) {
if (DEBUG)
dump("AlarmDB: " + aStr + "\n");
}
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
const ALARMDB_NAME = "alarms";
const ALARMDB_VERSION = 1;
const ALARMSTORE_NAME = "alarms";
this.AlarmDB = function AlarmDB() {
debug("AlarmDB()");
}
AlarmDB.prototype = {
__proto__: IndexedDBHelper.prototype,
init: function init() {
debug("init()");
this.initDBHelper(ALARMDB_NAME, ALARMDB_VERSION, [ALARMSTORE_NAME]);
},
upgradeSchema: function upgradeSchema(aTransaction, aDb,
aOldVersion, aNewVersion) {
debug("upgradeSchema()");
let objStore =
aDb.createObjectStore(ALARMSTORE_NAME,
{ keyPath: "id", autoIncrement: true });
objStore.createIndex("date", "date", { unique: false });
objStore.createIndex("ignoreTimezone", "ignoreTimezone", { unique: false });
objStore.createIndex("timezoneOffset", "timezoneOffset", { unique: false });
objStore.createIndex("data", "data", { unique: false });
objStore.createIndex("pageURL", "pageURL", { unique: false });
objStore.createIndex("manifestURL", "manifestURL", { unique: false });
debug("Created object stores and indexes");
},
/**
* @param aAlarm
* The record to be added.
* @param aSuccessCb
* Callback function to invoke with result ID.
* @param aErrorCb [optional]
* Callback function to invoke when there was an error.
*/
add: function add(aAlarm, aSuccessCb, aErrorCb) {
debug("add()");
this.newTxn("readwrite", ALARMSTORE_NAME, function txnCb(aTxn, aStore) {
debug("Going to add " + JSON.stringify(aAlarm));
aStore.put(aAlarm).onsuccess = function setTxnResult(aEvent) {
aTxn.result = aEvent.target.result;
debug("Request successful. New record ID: " + aTxn.result);
};
}, aSuccessCb, aErrorCb);
},
/**
* @param aId
* The ID of record to be removed.
* @param aManifestURL
* The manifest URL of the app that alarm belongs to.
* If null, directly remove the ID record; otherwise,
* need to check if the alarm belongs to this app.
* @param aSuccessCb
* Callback function to invoke with result.
* @param aErrorCb [optional]
* Callback function to invoke when there was an error.
*/
remove: function remove(aId, aManifestURL, aSuccessCb, aErrorCb) {
debug("remove()");
this.newTxn("readwrite", ALARMSTORE_NAME, function txnCb(aTxn, aStore) {
debug("Going to remove " + aId);
// Look up the existing record and compare the manifestURL
// to see if the alarm to be removed belongs to this app.
aStore.get(aId).onsuccess = function doRemove(aEvent) {
let alarm = aEvent.target.result;
if (!alarm) {
debug("Alarm doesn't exist. No need to remove it.");
return;
}
if (aManifestURL && aManifestURL != alarm.manifestURL) {
debug("Cannot remove the alarm added by other apps.");
return;
}
aStore.delete(aId);
};
}, aSuccessCb, aErrorCb);
},
/**
* @param aManifestURL
* The manifest URL of the app that alarms belong to.
* If null, directly return all alarms; otherwise,
* only return the alarms that belong to this app.
* @param aSuccessCb
* Callback function to invoke with result array.
* @param aErrorCb [optional]
* Callback function to invoke when there was an error.
*/
getAll: function getAll(aManifestURL, aSuccessCb, aErrorCb) {
debug("getAll()");
this.newTxn("readonly", ALARMSTORE_NAME, function txnCb(aTxn, aStore) {
if (!aTxn.result) {
aTxn.result = [];
}
let index = aStore.index("manifestURL");
index.mozGetAll(aManifestURL).onsuccess = function setTxnResult(aEvent) {
aTxn.result = aEvent.target.result;
debug("Request successful. Record count: " + aTxn.result.length);
};
}, aSuccessCb, aErrorCb);
}
};

View File

@ -1,121 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AlarmHalService.h"
namespace mozilla {
namespace dom {
namespace alarm {
using namespace hal;
NS_IMPL_ISUPPORTS(AlarmHalService, nsIAlarmHalService)
void
AlarmHalService::Init()
{
mAlarmEnabled = RegisterTheOneAlarmObserver(this);
if (!mAlarmEnabled) {
return;
}
RegisterSystemTimezoneChangeObserver(this);
RegisterSystemClockChangeObserver(this);
}
/* virtual */ AlarmHalService::~AlarmHalService()
{
if (mAlarmEnabled) {
UnregisterTheOneAlarmObserver();
UnregisterSystemTimezoneChangeObserver(this);
UnregisterSystemClockChangeObserver(this);
}
}
/* static */ StaticRefPtr<AlarmHalService> AlarmHalService::sSingleton;
/* static */ already_AddRefed<AlarmHalService>
AlarmHalService::GetInstance()
{
if (!sSingleton) {
sSingleton = new AlarmHalService();
sSingleton->Init();
ClearOnShutdown(&sSingleton);
}
RefPtr<AlarmHalService> service = sSingleton.get();
return service.forget();
}
NS_IMETHODIMP
AlarmHalService::SetAlarm(int32_t aSeconds, int32_t aNanoseconds, bool* aStatus)
{
if (!mAlarmEnabled) {
return NS_ERROR_FAILURE;
}
bool status = hal::SetAlarm(aSeconds, aNanoseconds);
if (status) {
*aStatus = status;
return NS_OK;
} else {
return NS_ERROR_FAILURE;
}
}
NS_IMETHODIMP
AlarmHalService::SetAlarmFiredCb(nsIAlarmFiredCb* aAlarmFiredCb)
{
mAlarmFiredCb = aAlarmFiredCb;
return NS_OK;
}
NS_IMETHODIMP
AlarmHalService::SetTimezoneChangedCb(nsITimezoneChangedCb* aTimeZoneChangedCb)
{
mTimezoneChangedCb = aTimeZoneChangedCb;
return NS_OK;
}
NS_IMETHODIMP
AlarmHalService::SetSystemClockChangedCb(
nsISystemClockChangedCb* aSystemClockChangedCb)
{
mSystemClockChangedCb = aSystemClockChangedCb;
return NS_OK;
}
void
AlarmHalService::Notify(const void_t& aVoid)
{
if (!mAlarmFiredCb) {
return;
}
mAlarmFiredCb->OnAlarmFired();
}
void
AlarmHalService::Notify(
const SystemTimezoneChangeInformation& aSystemTimezoneChangeInfo)
{
if (!mTimezoneChangedCb) {
return;
}
mTimezoneChangedCb->OnTimezoneChanged(
aSystemTimezoneChangeInfo.newTimezoneOffsetMinutes());
}
void
AlarmHalService::Notify(const int64_t& aClockDeltaMS)
{
if (!mSystemClockChangedCb) {
return;
}
mSystemClockChangedCb->OnSystemClockChanged(aClockDeltaMS);
}
} // namespace alarm
} // namespace dom
} // namespace mozilla

View File

@ -1,68 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_alarm_AlarmHalService_h
#define mozilla_dom_alarm_AlarmHalService_h
#include "base/basictypes.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Hal.h"
#include "mozilla/Services.h"
#include "nsIAlarmHalService.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
namespace mozilla {
namespace dom {
namespace alarm {
typedef Observer<void_t> AlarmObserver;
typedef Observer<hal::SystemTimezoneChangeInformation> SystemTimezoneChangeObserver;
typedef Observer<int64_t> SystemClockChangeObserver;
class AlarmHalService : public nsIAlarmHalService,
public AlarmObserver,
public SystemTimezoneChangeObserver,
public SystemClockChangeObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIALARMHALSERVICE
AlarmHalService()
: mAlarmEnabled(false)
{}
void Init();
static already_AddRefed<AlarmHalService> GetInstance();
// Implementing hal::AlarmObserver
void Notify(const void_t& aVoid) override;
// Implementing hal::SystemTimezoneChangeObserver
void Notify(const hal::SystemTimezoneChangeInformation& aSystemTimezoneChangeInfo) override;
// Implementing hal::SystemClockChangeObserver
void Notify(const int64_t& aClockDeltaMS) override;
private:
virtual ~AlarmHalService();
bool mAlarmEnabled;
static StaticRefPtr<AlarmHalService> sSingleton;
nsCOMPtr<nsIAlarmFiredCb> mAlarmFiredCb;
nsCOMPtr<nsITimezoneChangedCb> mTimezoneChangedCb;
nsCOMPtr<nsISystemClockChangedCb> mSystemClockChangedCb;
};
} // namespace alarm
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_alarm_AlarmHalService_h

View File

@ -1,633 +0,0 @@
/* 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/. */
"use strict";
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/AlarmDB.jsm");
Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://gre/modules/AppConstants.jsm");
function getLogger() {
var logger = Log.repository.getLogger("AlarmsService");
logger.addAppender(new Log.DumpAppender(new Log.BasicFormatter()));
logger.level = Log.Level.Debug;
return logger;
}
const logger = getLogger();
/* Only log in B2G */
function debug(aStr) {
AppConstants.MOZ_B2G && logger.debug(aStr);
}
this.EXPORTED_SYMBOLS = ["AlarmService"];
XPCOMUtils.defineLazyGetter(this, "appsService", function() {
return Cc["@mozilla.org/AppsService;1"].getService(Ci.nsIAppsService);
});
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
"@mozilla.org/parentprocessmessagemanager;1",
"nsIMessageListenerManager");
XPCOMUtils.defineLazyGetter(this, "messenger", function() {
return Cc["@mozilla.org/system-message-internal;1"]
.getService(Ci.nsISystemMessagesInternal);
});
XPCOMUtils.defineLazyGetter(this, "powerManagerService", function() {
return Cc["@mozilla.org/power/powermanagerservice;1"]
.getService(Ci.nsIPowerManagerService);
});
/**
* AlarmService provides an API to schedule alarms using the device's RTC.
*
* AlarmService is primarily used by the mozAlarms API (navigator.mozAlarms)
* which uses IPC to communicate with the service.
*
* AlarmService can also be used by Gecko code by importing the module and then
* using AlarmService.add() and AlarmService.remove(). Only Gecko code running
* in the parent process should do this.
*/
this.AlarmService = {
lastChromeId: 0,
init: function init() {
debug("init()");
Services.obs.addObserver(this, "profile-change-teardown", false);
Services.obs.addObserver(this, "webapps-clear-data",false);
this._currentTimezoneOffset = (new Date()).getTimezoneOffset();
let alarmHalService = this._alarmHalService =
Cc["@mozilla.org/alarmHalService;1"].getService(Ci.nsIAlarmHalService);
alarmHalService.setAlarmFiredCb(this._onAlarmFired.bind(this));
alarmHalService.setTimezoneChangedCb(this._onTimezoneChanged.bind(this));
alarmHalService.setSystemClockChangedCb(
this._onSystemClockChanged.bind(this));
// Add the messages to be listened to.
this._messages = ["AlarmsManager:GetAll",
"AlarmsManager:Add",
"AlarmsManager:Remove"];
this._messages.forEach(function addMessage(msgName) {
ppmm.addMessageListener(msgName, this);
}.bind(this));
// Set the indexeddb database.
this._db = new AlarmDB();
this._db.init();
// Variable to save alarms waiting to be set.
this._alarmQueue = [];
this._restoreAlarmsFromDb();
},
// Getter/setter to access the current alarm set in system.
_alarm: null,
get _currentAlarm() {
return this._alarm;
},
set _currentAlarm(aAlarm) {
this._alarm = aAlarm;
if (!aAlarm) {
return;
}
let alarmTimeInMs = this._getAlarmTime(aAlarm);
let ns = (alarmTimeInMs % 1000) * 1000000;
if (!this._alarmHalService.setAlarm(alarmTimeInMs / 1000, ns)) {
throw Components.results.NS_ERROR_FAILURE;
}
},
receiveMessage: function receiveMessage(aMessage) {
debug("receiveMessage(): " + aMessage.name);
let json = aMessage.json;
// To prevent the hacked child process from sending commands to parent
// to schedule alarms, we need to check its permission and manifest URL.
if (this._messages.indexOf(aMessage.name) != -1) {
if (!aMessage.target.assertPermission("alarms")) {
debug("Got message from a child process with no 'alarms' permission.");
return null;
}
if (!aMessage.target.assertContainApp(json.manifestURL)) {
debug("Got message from a child process containing illegal manifest URL.");
return null;
}
}
let mm = aMessage.target.QueryInterface(Ci.nsIMessageSender);
switch (aMessage.name) {
case "AlarmsManager:GetAll":
this._db.getAll(json.manifestURL,
function getAllSuccessCb(aAlarms) {
debug("Callback after getting alarms from database: " +
JSON.stringify(aAlarms));
this._sendAsyncMessage(mm, "GetAll", true, json.requestId, aAlarms);
}.bind(this),
function getAllErrorCb(aErrorMsg) {
this._sendAsyncMessage(mm, "GetAll", false, json.requestId, aErrorMsg);
}.bind(this));
break;
case "AlarmsManager:Add":
// Prepare a record for the new alarm to be added.
let newAlarm = { date: json.date,
ignoreTimezone: json.ignoreTimezone,
data: json.data,
pageURL: json.pageURL,
manifestURL: json.manifestURL };
this.add(newAlarm, null,
// Receives the alarm ID as the last argument.
this._sendAsyncMessage.bind(this, mm, "Add", true, json.requestId),
// Receives the error message as the last argument.
this._sendAsyncMessage.bind(this, mm, "Add", false, json.requestId));
break;
case "AlarmsManager:Remove":
this.remove(json.id, json.manifestURL);
break;
default:
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
break;
}
},
_sendAsyncMessage: function _sendAsyncMessage(aMessageManager, aMessageName,
aSuccess, aRequestId, aData) {
debug("_sendAsyncMessage()");
if (!aMessageManager) {
debug("Invalid message manager: null");
throw Components.results.NS_ERROR_FAILURE;
}
let json = null;
switch (aMessageName) {
case "Add":
json = aSuccess ?
{ requestId: aRequestId, id: aData } :
{ requestId: aRequestId, errorMsg: aData };
break;
case "GetAll":
json = aSuccess ?
{ requestId: aRequestId, alarms: aData } :
{ requestId: aRequestId, errorMsg: aData };
break;
default:
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
break;
}
aMessageManager.sendAsyncMessage("AlarmsManager:" + aMessageName +
":Return:" + (aSuccess ? "OK" : "KO"),
json);
},
_removeAlarmFromDb: function _removeAlarmFromDb(aId, aManifestURL,
aRemoveSuccessCb) {
debug("_removeAlarmFromDb()");
// If the aRemoveSuccessCb is undefined or null, set a dummy callback for
// it which is needed for _db.remove().
if (!aRemoveSuccessCb) {
aRemoveSuccessCb = function removeSuccessCb() {
debug("Remove alarm from DB successfully.");
};
}
// Is this a chrome alarm?
if (aId < 0) {
aRemoveSuccessCb();
return;
}
this._db.remove(aId, aManifestURL, aRemoveSuccessCb,
function removeErrorCb(aErrorMsg) {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
});
},
/**
* Create a copy of the alarm that does not expose internal fields to
* receivers and sticks to the public |respectTimezone| API rather than the
* boolean |ignoreTimezone| field.
*/
_publicAlarm: function _publicAlarm(aAlarm) {
let alarm = { "id": aAlarm.id,
"date": aAlarm.date,
"respectTimezone": aAlarm.ignoreTimezone ?
"ignoreTimezone" : "honorTimezone",
"data": aAlarm.data };
return alarm;
},
_fireSystemMessage: function _fireSystemMessage(aAlarm) {
debug("Fire system message: " + JSON.stringify(aAlarm));
let manifestURI = Services.io.newURI(aAlarm.manifestURL, null, null);
let pageURI = Services.io.newURI(aAlarm.pageURL, null, null);
messenger.sendMessage("alarm",
this._publicAlarm(aAlarm),
pageURI,
manifestURI);
},
_notifyAlarmObserver: function _notifyAlarmObserver(aAlarm) {
debug("_notifyAlarmObserver()");
let wakeLock = powerManagerService.newWakeLock("cpu");
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.initWithCallback(() => {
debug("_notifyAlarmObserver - timeout()");
if (aAlarm.manifestURL) {
this._fireSystemMessage(aAlarm);
} else if (typeof aAlarm.alarmFiredCb === "function") {
aAlarm.alarmFiredCb(this._publicAlarm(aAlarm));
}
wakeLock.unlock();
}, 0, Ci.nsITimer.TYPE_ONE_SHOT);
},
_onAlarmFired: function _onAlarmFired() {
debug("_onAlarmFired()");
if (this._currentAlarm) {
let currentAlarmTime = this._getAlarmTime(this._currentAlarm);
// If a alarm fired before the actual time that the current
// alarm should occur, we reset this current alarm.
if (currentAlarmTime > Date.now()) {
let currentAlarm = this._currentAlarm;
this._currentAlarm = currentAlarm;
this._debugCurrentAlarm();
return;
}
this._removeAlarmFromDb(this._currentAlarm.id, null);
// We need to clear the current alarm before notifying because chrome
// alarms may add a new alarm during their callback, and we do not want
// to clobber it.
let firingAlarm = this._currentAlarm;
this._currentAlarm = null;
this._notifyAlarmObserver(firingAlarm);
}
// Reset the next alarm from the queue.
let alarmQueue = this._alarmQueue;
while (alarmQueue.length > 0) {
let nextAlarm = alarmQueue.shift();
let nextAlarmTime = this._getAlarmTime(nextAlarm);
// If the next alarm has been expired, directly notify the observer.
// it instead of setting it.
if (nextAlarmTime <= Date.now()) {
this._removeAlarmFromDb(nextAlarm.id, null);
this._notifyAlarmObserver(nextAlarm);
} else {
this._currentAlarm = nextAlarm;
break;
}
}
this._debugCurrentAlarm();
},
_onTimezoneChanged: function _onTimezoneChanged(aTimezoneOffset) {
debug("_onTimezoneChanged()");
this._currentTimezoneOffset = aTimezoneOffset;
this._restoreAlarmsFromDb();
},
_onSystemClockChanged: function _onSystemClockChanged(aClockDeltaMS) {
debug("_onSystemClockChanged");
this._restoreAlarmsFromDb();
},
_restoreAlarmsFromDb: function _restoreAlarmsFromDb() {
debug("_restoreAlarmsFromDb()");
this._db.getAll(null,
function getAllSuccessCb(aAlarms) {
debug("Callback after getting alarms from database: " +
JSON.stringify(aAlarms));
// Clear any alarms set or queued in the cache if coming from db.
let alarmQueue = this._alarmQueue;
if (this._currentAlarm) {
alarmQueue.unshift(this._currentAlarm);
this._currentAlarm = null;
}
for (let i = 0; i < alarmQueue.length;) {
if (alarmQueue[i]['id'] < 0) {
++i;
continue;
}
alarmQueue.splice(i, 1);
}
// Only restore the alarm that's not yet expired; otherwise, remove it
// from the database and notify the observer.
aAlarms.forEach(function addAlarm(aAlarm) {
if ("manifestURL" in aAlarm && aAlarm.manifestURL &&
this._getAlarmTime(aAlarm) > Date.now()) {
alarmQueue.push(aAlarm);
} else {
this._removeAlarmFromDb(aAlarm.id, null);
this._notifyAlarmObserver(aAlarm);
}
}.bind(this));
// Set the next alarm from the queue.
if (alarmQueue.length) {
alarmQueue.sort(this._sortAlarmByTimeStamps.bind(this));
this._currentAlarm = alarmQueue.shift();
}
this._debugCurrentAlarm();
}.bind(this),
function getAllErrorCb(aErrorMsg) {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
});
},
_getAlarmTime: function _getAlarmTime(aAlarm) {
// Avoid casting a Date object to a Date again to
// preserve milliseconds. See bug 810973.
let alarmTime;
if (aAlarm.date instanceof Date) {
alarmTime = aAlarm.date.getTime();
} else {
alarmTime = (new Date(aAlarm.date)).getTime();
}
// For an alarm specified with "ignoreTimezone", it must be fired respect
// to the user's timezone. Supposing an alarm was set at 7:00pm at Tokyo,
// it must be gone off at 7:00pm respect to Paris' local time when the user
// is located at Paris. We can adjust the alarm UTC time by calculating
// the difference of the orginal timezone and the current timezone.
if (aAlarm.ignoreTimezone) {
alarmTime +=
(this._currentTimezoneOffset - aAlarm.timezoneOffset) * 60000;
}
return alarmTime;
},
_sortAlarmByTimeStamps: function _sortAlarmByTimeStamps(aAlarm1, aAlarm2) {
return this._getAlarmTime(aAlarm1) - this._getAlarmTime(aAlarm2);
},
_debugCurrentAlarm: function _debugCurrentAlarm() {
debug("Current alarm: " + JSON.stringify(this._currentAlarm));
debug("Alarm queue: " + JSON.stringify(this._alarmQueue));
},
/**
*
* Add a new alarm. This will set the RTC to fire at the selected date and
* notify the caller. Notifications are delivered via System Messages if the
* alarm is added on behalf of a app. Otherwise aAlarmFiredCb is called.
*
* @param object aNewAlarm
* Should contain the following literal properties:
* - |date| date: when the alarm should timeout.
* - |ignoreTimezone| boolean: See [1] for the details.
* - |manifestURL| string: Manifest of app on whose behalf the alarm
* is added.
* - |pageURL| string: The page in the app that receives the system
* message.
* - |data| object [optional]: Data that can be stored in DB.
* @param function aAlarmFiredCb
* Callback function invoked when the alarm is fired.
* It receives a single argument, the alarm object.
* May be null.
* @param function aSuccessCb
* Callback function to receive an alarm ID (number).
* @param function aErrorCb
* Callback function to receive an error message (string).
* @returns void
*
* Notes:
* [1] https://wiki.mozilla.org/WebAPI/AlarmAPI#Proposed_API
*/
add: function(aNewAlarm, aAlarmFiredCb, aSuccessCb, aErrorCb) {
debug("add(" + aNewAlarm.date + ")");
aSuccessCb = aSuccessCb || function() {};
aErrorCb = aErrorCb || function() {};
if (!aNewAlarm) {
aErrorCb("alarm is null");
return;
}
if (!aNewAlarm.date) {
aErrorCb("alarm.date is null");
return;
}
aNewAlarm['timezoneOffset'] = this._currentTimezoneOffset;
if ("manifestURL" in aNewAlarm) {
this._db.add(aNewAlarm,
function addSuccessCb(aNewId) {
debug("Callback after adding alarm in database.");
this.processNewAlarm(aNewAlarm, aNewId, aAlarmFiredCb, aSuccessCb);
}.bind(this),
function addErrorCb(aErrorMsg) {
aErrorCb(aErrorMsg);
}.bind(this));
} else {
// alarms without manifests are managed by chrome code. For them we use
// negative IDs.
this.processNewAlarm(aNewAlarm, --this.lastChromeId, aAlarmFiredCb,
aSuccessCb);
}
},
processNewAlarm: function(aNewAlarm, aNewId, aAlarmFiredCb, aSuccessCb) {
aNewAlarm['id'] = aNewId;
// Now that the alarm has been added to the database, we can tack on
// the non-serializable callback to the in-memory object.
aNewAlarm['alarmFiredCb'] = aAlarmFiredCb;
// If the new alarm already expired at this moment, we directly
// notify this alarm
let newAlarmTime = this._getAlarmTime(aNewAlarm);
if (newAlarmTime < Date.now()) {
aSuccessCb(aNewId);
this._removeAlarmFromDb(aNewAlarm.id, null);
this._notifyAlarmObserver(aNewAlarm);
return;
}
// If there is no alarm being set in system, set the new alarm.
if (this._currentAlarm == null) {
this._currentAlarm = aNewAlarm;
this._debugCurrentAlarm();
aSuccessCb(aNewId);
return;
}
// If the new alarm is earlier than the current alarm, swap them and
// push the previous alarm back to the queue.
let alarmQueue = this._alarmQueue;
let currentAlarmTime = this._getAlarmTime(this._currentAlarm);
if (newAlarmTime < currentAlarmTime) {
alarmQueue.unshift(this._currentAlarm);
this._currentAlarm = aNewAlarm;
this._debugCurrentAlarm();
aSuccessCb(aNewId);
return;
}
// Push the new alarm in the queue.
alarmQueue.push(aNewAlarm);
alarmQueue.sort(this._sortAlarmByTimeStamps.bind(this));
this._debugCurrentAlarm();
aSuccessCb(aNewId);
},
/*
* Remove the alarm associated with an ID.
*
* @param number aAlarmId
* The ID of the alarm to be removed.
* @param string aManifestURL
* Manifest URL for application which added the alarm. (Optional)
* @returns void
*/
remove: function(aAlarmId, aManifestURL) {
debug("remove(" + aAlarmId + ", " + aManifestURL + ")");
this._removeAlarmFromDb(aAlarmId, aManifestURL,
function removeSuccessCb() {
debug("Callback after removing alarm from database.");
// If there are no alarms set, nothing to do.
if (!this._currentAlarm) {
debug("No alarms set.");
return;
}
// Check if the alarm to be removed is in the queue and whether it
// belongs to the requesting app.
let alarmQueue = this._alarmQueue;
if (this._currentAlarm.id != aAlarmId ||
this._currentAlarm.manifestURL != aManifestURL) {
for (let i = 0; i < alarmQueue.length; i++) {
if (alarmQueue[i].id == aAlarmId &&
alarmQueue[i].manifestURL == aManifestURL) {
alarmQueue.splice(i, 1);
break;
}
}
this._debugCurrentAlarm();
return;
}
// The alarm to be removed is the current alarm reset the next alarm
// from the queue if any.
if (alarmQueue.length) {
this._currentAlarm = alarmQueue.shift();
this._debugCurrentAlarm();
return;
}
// No alarm waiting to be set in the queue.
this._currentAlarm = null;
this._debugCurrentAlarm();
}.bind(this));
},
observe: function(aSubject, aTopic, aData) {
debug("observe(): " + aTopic);
switch (aTopic) {
case "profile-change-teardown":
this.uninit();
break;
case "webapps-clear-data":
let params =
aSubject.QueryInterface(Ci.mozIApplicationClearPrivateDataParams);
if (!params) {
debug("Error! Fail to remove alarms for an uninstalled app.");
return;
}
// Only remove alarms for apps.
if (params.browserOnly) {
return;
}
let manifestURL = appsService.getManifestURLByLocalId(params.appId);
if (!manifestURL) {
debug("Error! Fail to remove alarms for an uninstalled app.");
return;
}
this._db.getAll(manifestURL,
function getAllSuccessCb(aAlarms) {
aAlarms.forEach(function removeAlarm(aAlarm) {
this.remove(aAlarm.id, manifestURL);
}, this);
}.bind(this),
function getAllErrorCb(aErrorMsg) {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
});
break;
}
},
uninit: function uninit() {
debug("uninit()");
Services.obs.removeObserver(this, "profile-change-teardown");
Services.obs.removeObserver(this, "webapps-clear-data");
this._messages.forEach(function(aMsgName) {
ppmm.removeMessageListener(aMsgName, this);
}.bind(this));
ppmm = null;
if (this._db) {
this._db.close();
}
this._db = null;
this._alarmHalService = null;
}
}
AlarmService.init();

View File

@ -1,227 +0,0 @@
/* 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/. */
"use strict";
/* static functions */
const DEBUG = false;
const REQUEST_CPU_LOCK_TIMEOUT = 10 * 1000; // 10 seconds.
function debug(aStr) {
if (DEBUG)
dump("AlarmsManager: " + aStr + "\n");
}
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "gPowerManagerService",
"@mozilla.org/power/powermanagerservice;1",
"nsIPowerManagerService");
function AlarmsManager() {
debug("Constructor");
// A <requestId, {cpuLock, timer}> map.
this._cpuLockDict = new Map();
}
AlarmsManager.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
contractID : "@mozilla.org/alarmsManager;1",
classID : Components.ID("{fea1e884-9b05-11e1-9b64-87a7016c3860}"),
QueryInterface : XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer,
Ci.nsISupportsWeakReference,
Ci.nsIObserver]),
add: function add(aDate, aRespectTimezone, aData) {
debug("add()");
if (!this._manifestURL) {
debug("Cannot add alarms for non-installed apps.");
throw Components.results.NS_ERROR_FAILURE;
}
if (!aDate) {
throw Components.results.NS_ERROR_INVALID_ARG;
}
let isIgnoreTimezone = true;
switch (aRespectTimezone) {
case "honorTimezone":
isIgnoreTimezone = false;
break;
case "ignoreTimezone":
isIgnoreTimezone = true;
break;
default:
throw Components.results.NS_ERROR_INVALID_ARG;
break;
}
let data = aData;
if (aData) {
// Run JSON.stringify() in the sand box with the principal of the calling
// web page to ensure no cross-origin object is involved. A "Permission
// Denied" error will be thrown in case of privilege violation.
let sandbox = new Cu.Sandbox(Cu.getWebIDLCallerPrincipal());
sandbox.data = aData;
data = JSON.parse(Cu.evalInSandbox("JSON.stringify(data)", sandbox));
}
let request = this.createRequest();
let requestId = this.getRequestId(request);
this._lockCpuForRequest(requestId);
this._cpmm.sendAsyncMessage("AlarmsManager:Add",
{ requestId: requestId,
date: aDate,
ignoreTimezone: isIgnoreTimezone,
data: data,
pageURL: this._pageURL,
manifestURL: this._manifestURL });
return request;
},
remove: function remove(aId) {
debug("remove()");
this._cpmm.sendAsyncMessage("AlarmsManager:Remove",
{ id: aId, manifestURL: this._manifestURL });
},
getAll: function getAll() {
debug("getAll()");
let request = this.createRequest();
this._cpmm.sendAsyncMessage("AlarmsManager:GetAll",
{ requestId: this.getRequestId(request),
manifestURL: this._manifestURL });
return request;
},
receiveMessage: function receiveMessage(aMessage) {
debug("receiveMessage(): " + aMessage.name);
let json = aMessage.json;
let request = this.getRequest(json.requestId);
if (!request) {
debug("No request stored! " + json.requestId);
return;
}
switch (aMessage.name) {
case "AlarmsManager:Add:Return:OK":
this._unlockCpuForRequest(json.requestId);
Services.DOMRequest.fireSuccess(request, json.id);
break;
case "AlarmsManager:GetAll:Return:OK":
// We don't need to expose everything to the web content.
let alarms = [];
json.alarms.forEach(function trimAlarmInfo(aAlarm) {
let alarm = { "id": aAlarm.id,
"date": aAlarm.date,
"respectTimezone": aAlarm.ignoreTimezone ?
"ignoreTimezone" : "honorTimezone",
"data": aAlarm.data };
alarms.push(alarm);
});
Services.DOMRequest.fireSuccess(request,
Cu.cloneInto(alarms, this._window));
break;
case "AlarmsManager:Add:Return:KO":
this._unlockCpuForRequest(json.requestId);
Services.DOMRequest.fireError(request, json.errorMsg);
break;
case "AlarmsManager:GetAll:Return:KO":
Services.DOMRequest.fireError(request, json.errorMsg);
break;
default:
debug("Wrong message: " + aMessage.name);
break;
}
this.removeRequest(json.requestId);
},
// nsIDOMGlobalPropertyInitializer implementation
init: function init(aWindow) {
debug("init()");
this._cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
.getService(Ci.nsISyncMessageSender);
// Add the valid messages to be listened.
this.initDOMRequestHelper(aWindow, ["AlarmsManager:Add:Return:OK",
"AlarmsManager:Add:Return:KO",
"AlarmsManager:GetAll:Return:OK",
"AlarmsManager:GetAll:Return:KO"]);
// Get the manifest URL if this is an installed app
let appsService = Cc["@mozilla.org/AppsService;1"]
.getService(Ci.nsIAppsService);
let principal = aWindow.document.nodePrincipal;
this._pageURL = principal.URI.spec;
this._manifestURL = appsService.getManifestURLByLocalId(principal.appId);
this._window = aWindow;
},
// Called from DOMRequestIpcHelper.
uninit: function uninit() {
debug("uninit()");
},
_lockCpuForRequest: function (aRequestId) {
if (this._cpuLockDict.has(aRequestId)) {
debug('Cpu wakelock for request ' + aRequestId + ' has been acquired. ' +
'You may call this function repeatedly or requestId is collision.');
return;
}
// Acquire a lock for given request and save for lookup lately.
debug('Acquire cpu lock for request ' + aRequestId);
let cpuLockInfo = {
cpuLock: gPowerManagerService.newWakeLock("cpu"),
timer: Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer)
};
this._cpuLockDict.set(aRequestId, cpuLockInfo);
// Start a timer to prevent from non-responding request.
cpuLockInfo.timer.initWithCallback(() => {
debug('Request timeout! Release the cpu lock');
this._unlockCpuForRequest(aRequestId);
}, REQUEST_CPU_LOCK_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT);
},
_unlockCpuForRequest: function(aRequestId) {
let cpuLockInfo = this._cpuLockDict.get(aRequestId);
if (!cpuLockInfo) {
debug('The cpu lock for requestId ' + aRequestId + ' is either invalid ' +
'or has been released.');
return;
}
// Release the cpu lock and cancel the timer.
debug('Release the cpu lock for ' + aRequestId);
cpuLockInfo.cpuLock.unlock();
cpuLockInfo.timer.cancel();
this._cpuLockDict.delete(aRequestId);
},
}
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AlarmsManager])

View File

@ -1,2 +0,0 @@
component {fea1e884-9b05-11e1-9b64-87a7016c3860} AlarmsManager.js
contract @mozilla.org/alarmsManager;1 {fea1e884-9b05-11e1-9b64-87a7016c3860}

View File

@ -1,39 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
XPIDL_SOURCES += [
'nsIAlarmHalService.idl',
]
XPIDL_MODULE = 'dom_alarm'
EXPORTS.mozilla.dom.alarm += [
'AlarmHalService.h',
]
SOURCES += [
'AlarmHalService.cpp',
]
EXTRA_COMPONENTS += [
'AlarmsManager.js',
'AlarmsManager.manifest',
]
EXTRA_JS_MODULES += [
'AlarmDB.jsm',
'AlarmService.jsm',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
MOCHITEST_MANIFESTS += ['test/mochitest.ini']
MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell.ini']

View File

@ -1,40 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
[scriptable, function, uuid(53dec7f9-bb51-4c3a-98ab-80d5d750c9dd)]
interface nsIAlarmFiredCb : nsISupports
{
void onAlarmFired();
};
[scriptable, function, uuid(e6662911-c066-4358-9388-8661065c65a2)]
interface nsITimezoneChangedCb : nsISupports
{
void onTimezoneChanged(in int32_t aTimezoneOffset);
};
[scriptable, function, uuid(46ece987-a3ec-4124-906f-d99c83296ac6)]
interface nsISystemClockChangedCb : nsISupports
{
void onSystemClockChanged(in int32_t aClockDeltaMS);
};
%{C++
#define NS_ALARMHALSERVICE_CID { 0x7dafea4c, 0x7163, 0x4b70, { 0x95, 0x4e, 0x5a, 0xd4, 0x09, 0x94, 0x83, 0xd7 } }
#define ALARMHALSERVICE_CONTRACTID "@mozilla.org/alarmHalService;1"
%}
[scriptable, uuid(35074214-f50d-4f9a-b173-8d564dfa657d)]
interface nsIAlarmHalService : nsISupports
{
bool setAlarm(in int32_t aSeconds, in int32_t aNanoseconds);
void setAlarmFiredCb(in nsIAlarmFiredCb aAlarmFiredCb);
void setTimezoneChangedCb(in nsITimezoneChangedCb aTimezoneChangedCb);
void setSystemClockChangedCb(in nsISystemClockChangedCb aSystemClockChangedCb);
};

View File

@ -1,7 +0,0 @@
[DEFAULT]
run-if = buildapp == 'b2g' || buildapp == 'mulet'
support-files =
file_empty.html
system_message_chrome_script.js
[test_alarm_permitted_app.html]

View File

@ -1,2 +0,0 @@
<!DOCTYPE html>
<html><head></head><body><span id="text">Nothing to see here</span><iframe name="subframe"></iframe></body></html>

View File

@ -1,14 +0,0 @@
[DEFAULT]
run-if = buildapp == 'b2g' || buildapp == 'mulet'
support-files =
file_empty.html
system_message_chrome_script.js
[test_alarm_add_data.html]
[test_alarm_add_date.html]
[test_alarm_add_respectTimezone.html]
[test_alarm_non_permitted_app.html]
[test_alarm_remove.html]
[test_bug1015540.html]
[test_bug1037079.html]
[test_bug1090896.html]

View File

@ -1,18 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
var { classes: Cc, interfaces: Ci } = Components;
const systemMessenger = Cc["@mozilla.org/system-message-internal;1"]
.getService(Ci.nsISystemMessagesInternal);
const ioService = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
addMessageListener("trigger-register-page", function(aData) {
systemMessenger.registerPage(aData.type,
ioService.newURI(aData.pageURL, null, null),
ioService.newURI(aData.manifestURL, null, null));
sendAsyncMessage("page-registered");
});

View File

@ -1,246 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test data Paramter for Alarm API</title>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript">
"use strict";
// Verify passing {} for the data paramter
function testEmptyObject() {
var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
var data = {};
var domRequest;
try {
domRequest = navigator.mozAlarms.add(tomorrow, "honorTimezone", data);
} catch (e) {
ok(false,
"Unexpected exception trying to add alarm for tomorrow for empty object test.");
return testEmptyList();
}
domRequest.onsuccess = function(e) {
var alarmId = e.target.result;
// Confirm the alarm added has the data we requested
var allReq;
try {
allReq = navigator.mozAlarms.getAll();
} catch (e) {
ok(false,
"Unexpected exception trying to get all alarms for empty object test.");
return testEmptyList();
}
allReq.onsuccess = function(ev) {
navigator.mozAlarms.remove(alarmId);
var found = false;
ev.target.result.forEach(function(alarm, i, arr) {
if (alarm.id == alarmId) {
// Found the one we added
ok(Object.keys(alarm.data).length === 0,
"Empty object passed for data parameter for new alarm.");
found = true;
}
});
if (!found) {
ok(false, "Couldn't find alarm that was added for empty object test.");
}
testEmptyList();
}
allReq.onerror = function(e) {
ok(false, "Unable to get all alarms for empty object test.");
testEmptyList();
}
};
domRequest.onerror = function(e) {
ok(false, "Unable to add alarm for tomorrow for empty object test.");
testEmptyList();
};
}
// Verify passing [] for the data paramter
function testEmptyList() {
var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
var data = [];
var domRequest;
try {
domRequest = navigator.mozAlarms.add(tomorrow, "honorTimezone", data);
} catch (e) {
ok(false,
"Unexpected exception trying to add alarm for tomorrow for empty list test.");
return testNull();
}
domRequest.onsuccess = function(e) {
var alarmId = e.target.result;
// Confirm the alarm added has the data we requested
var allReq;
try {
allReq = navigator.mozAlarms.getAll();
} catch (e) {
ok(false,
"Unexpected exception trying to get all alarms for empty list test.");
return testNull();
}
allReq.onsuccess = function(ev) {
navigator.mozAlarms.remove(alarmId);
var found = false;
ev.target.result.forEach(function(alarm, i, arr) {
if (alarm.id == alarmId) {
// Found the one we added
ok(alarm.data.length === 0,
"Empty list passed for data parameter for new alarm.");
found = true;
}
});
if (!found) {
ok(false, "Couldn't find alarm that was added for empty list test.");
}
testNull();
}
allReq.onerror = function(e) {
ok(false, "Unable to get all alarms for empty list test.");
testNull();
}
};
domRequest.onerror = function(e) {
ok(false, "Unable to add alarm for tomorrow for empty list test.");
testNull();
};
}
// Verify passing null for the data paramter
function testNull() {
var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
var data = null;
var domRequest;
try {
domRequest = navigator.mozAlarms.add(tomorrow, "honorTimezone", data);
} catch (e) {
ok(false,
"Unexpected exception trying to add alarm for tomorrow for null test.");
return SimpleTest.finish();
}
domRequest.onsuccess = function(e) {
var alarmId = e.target.result;
// Confirm the alarm added has the data we requested
var allReq;
try {
allReq = navigator.mozAlarms.getAll();
} catch (e) {
ok(false,
"Unexpected exception trying to get all alarms for null test.");
return SimpleTest.finish();
}
allReq.onsuccess = function(ev) {
navigator.mozAlarms.remove(alarmId);
var found = false;
ev.target.result.forEach(function(alarm, i, arr) {
if (alarm.id == alarmId) {
// Found the one we added
ok(alarm.data === null,
"Null passed for data parameter for new alarm.");
found = true;
}
});
if (!found) {
ok(false, "Couldn't find alarm that was added for null test.");
}
SimpleTest.finish();
}
allReq.onerror = function(e) {
ok(false, "Unable to get all alarms for null test.");
SimpleTest.finish();
}
};
domRequest.onerror = function(e) {
ok(false, "Unable to add alarm for tomorrow for null test.");
SimpleTest.finish();
};
}
function startTests() {
SpecialPowers.pushPrefEnv({
"set": [["dom.mozAlarms.enabled", true]]
}, function() {
var isAllowedToTest = true;
if (navigator.appVersion.indexOf("Android") !== -1) {
ok(true, "mozAlarms is not allowed on Android for now. " +
"TODO Bug 863557.");
isAllowedToTest = false;
} else if (SpecialPowers.wrap(document).nodePrincipal.appStatus ==
SpecialPowers.Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED) {
ok(true, "mozAlarms is not allowed for non-installed apps. " +
"TODO Bug 876981.");
isAllowedToTest = false;
}
if (isAllowedToTest) {
ok(true, "Start to test...");
testEmptyObject();
} else {
// A sanity check to make sure we must run tests on Firefox OS (B2G).
if (navigator.userAgent.indexOf("Mobile") != -1 &&
navigator.appVersion.indexOf("Android") == -1) {
ok(false, "Should run the test on Firefox OS (B2G)!");
}
SimpleTest.finish();
}
});
}
SimpleTest.expectAssertions(0, 9);
SimpleTest.waitForExplicitFinish();
if (SpecialPowers.hasPermission("alarms", document)) {
startTests();
} else {
// Add the permission and reload the page so it propogates
SpecialPowers.addPermission("alarms", true, document);
window.location.reload();
}
</script>
</pre>
</body>
</html>

View File

@ -1,146 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test date Paramter for Alarm API</title>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript">
"use strict";
// Verify passing a Date in the future doesn't fail
function testFutureDate() {
var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
var domRequest;
try {
domRequest = navigator.mozAlarms.add(tomorrow, "honorTimezone", {});
} catch (e) {
ok(false,
"Unexpected exception trying to add alarm for tomorrow.");
// Proceed to next test.
return testPastDate();
}
domRequest.onsuccess = function(e) {
navigator.mozAlarms.remove(e.target.result);
ok(true, "Add alarm for future date.");
// Awesome, no error so proceed to next test.
testPastDate();
};
domRequest.onerror = function(e) {
ok(false, "Unable to add alarm for tomorrow`.");
// Proceed to next test.
testPastDate();
};
}
// Verify passing a Date that's already past doesn't fail (it should fire immediately).
function testPastDate() {
var yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
var domRequest;
try {
domRequest = navigator.mozAlarms.add(yesterday, "honorTimezone", {});
} catch (e) {
ok(false,
"Unexpected exception trying to add alarm for yesterday.");
// Move on to the next test.
return testNullDate();
}
domRequest.onsuccess = function(e) {
navigator.mozAlarms.remove(e.target.result);
ok(true, "Should be able to add alarm for already past date, which should fire immediately.");
// Move on to the next test.
testNullDate();
};
domRequest.onerror = function(e) {
ok(false, "Unable to add alarm for yesterday.");
// Move on to the next test.
testNullDate();
}
}
// Verify passing null does indeed fail
function testNullDate() {
try {
navigator.mozAlarms.add(null, "honorTimezone", {});
ok(false, "Expected an exception to be thrown for alarm with null date.");
} catch(e) {
ok(true, "Exception thrown for alarm with null date.");
}
// Move on to the next test.
testInvalidTimeZone()
}
function testInvalidTimeZone() {
try {
navigator.mozAlarms.add(new Date(), "badTimeZoneArg", {});
ok(false, "Expected an exception to be thrown while testing bad time zone arg.");
} catch(e) {
ok(true, "Exception thrown while testing bad time zone arg.");
}
SimpleTest.finish();
}
function startTests() {
SpecialPowers.pushPrefEnv({
"set": [["dom.mozAlarms.enabled", true]]
}, function() {
var isAllowedToTest = true;
if (navigator.appVersion.indexOf("Android") !== -1) {
ok(true, "mozAlarms is not allowed on Android for now. " +
"TODO Bug 863557.");
isAllowedToTest = false;
} else if (SpecialPowers.wrap(document).nodePrincipal.appStatus ==
SpecialPowers.Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED) {
ok(true, "mozAlarms is not allowed for non-installed apps. " +
"TODO Bug 876981.");
isAllowedToTest = false;
}
if (isAllowedToTest) {
ok(true, "Start to test...");
testFutureDate();
} else {
// A sanity check to make sure we must run tests on Firefox OS (B2G).
if (navigator.userAgent.indexOf("Mobile") != -1 &&
navigator.appVersion.indexOf("Android") == -1) {
ok(false, "Should run the test on Firefox OS (B2G)!");
}
SimpleTest.finish();
}
});
}
SimpleTest.expectAssertions(0, 9);
SimpleTest.waitForExplicitFinish();
if (SpecialPowers.hasPermission("alarms", document)) {
startTests();
} else {
// Add the permissions and reload so they propogate
SpecialPowers.addPermission("alarms", true, document);
window.location.reload();
}
</script>
</pre>
</body>
</html>

View File

@ -1,170 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test respectTimezone Parameter for Alarm API</title>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript">
"use strict";
// Verify passing `honorTimezone` doesn't fail
function testHonorTimezone(tomorrow) {
var domRequest;
try {
domRequest = navigator.mozAlarms.add(tomorrow, "honorTimezone", {});
} catch (e) {
ok(false,
"Unexpected exception trying to add alarm for tomorrow with `honorTimezone`.");
return testIgnoreTimezone(tomorrow);
}
domRequest.onsuccess = function(e) {
navigator.mozAlarms.remove(e.target.result);
ok(true, "Passing `honorTimezone` for repectTimezone argument.");
testIgnoreTimezone(tomorrow);
};
domRequest.onerror = function(e) {
ok(false, "Unable to add alarm for tomorrow with `honorTimezone`.");
testIgnoreTimezone(tomorrow);
};
}
// Verify passing `ignoreTimezone` doesn't fail
function testIgnoreTimezone(tomorrow) {
var domRequest;
try {
domRequest = navigator.mozAlarms.add(tomorrow, "ignoreTimezone", {});
} catch (e) {
ok(false,
"Unexpected exception trying to add alarm for tomorrow with `ignoreTimezone`.");
return testBadInput(tomorrow);
}
domRequest.onsuccess = function(e) {
navigator.mozAlarms.remove(e.target.result);
ok(true, "Passing `ignoreTimezone` for respectTimezone argument.");
testBadInput(tomorrow);
};
domRequest.onerror = function(e) {
ok(false, "Unable to add alarm for tomorrow with `ignoreTimezone`.");
testBadInput(tomorrow);
}
}
// Verify passing a string that's not `honorTimezone` or `ignoreTimezone`
// does fail
function testBadInput(tomorrow) {
var domRequest;
try {
domRequest = navigator.mozAlarms.add(tomorrow, "badinput", {});
} catch (e) {
ok(true, "Bad input for repectTimezone does indeed fail.");
// Errors, as it should. On to the next test.
return testNull(tomorrow);
}
domRequest.onsuccess = function(e) {
// Welp, this shouldn't happen
ok(false, "Malformed input accepted for `respectTimezone` param.");
testNull(tomorrow);
};
}
// Verify passing null does indeed fail
function testNull(tomorrow) {
var domRequest;
try {
domRequest = navigator.mozAlarms.add(tomorrow, null, {});
} catch(e) {
ok(true, "Passing null for respectTimezone does indeed fail.");
// Exception thrown, on to the next test
return testMisspelt(tomorrow);
}
domRequest.onsuccess = function(e) {
// Null should not be valid
ok(false, "Null should not be accepted as input for `respectTimezone` param.");
testMisspelt(tomorrow);
};
}
// Verify that misspelling does indeed fail
function testMisspelt(tomorrow) {
var domRequest;
try {
// Missing the e in `ignoreTimezone`
domRequest = navigator.mozAlarms.add(tomorrow, "ignoreTimzone", {});
} catch (e) {
ok(true, "Misspelling `ignoreTimezone` does indeed fail.");
// Exception thrown, all is right in the world.
// All done with tests now.
return SimpleTest.finish();
}
domRequest.onsuccess = function(e) {
// The misspelled word should not be valid
ok(false, "Misspelt parameter should fail.");
SimpleTest.finish();
};
}
function startTests() {
SpecialPowers.pushPrefEnv({
"set": [["dom.mozAlarms.enabled", true]]
}, function() {
var isAllowedToTest = true;
if (navigator.appVersion.indexOf("Android") !== -1) {
ok(true, "mozAlarms is not allowed on Android for now. " +
"TODO Bug 863557.");
isAllowedToTest = false;
} else if (SpecialPowers.wrap(document).nodePrincipal.appStatus ==
SpecialPowers.Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED) {
ok(true, "mozAlarms is not allowed for non-installed apps. " +
"TODO Bug 876981.");
isAllowedToTest = false;
}
if (isAllowedToTest) {
ok(true, "Start to test...");
// Arbitrary date to use for tests
var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
// Kick off the tests
testHonorTimezone(tomorrow);
} else {
// A sanity check to make sure we must run tests on Firefox OS (B2G).
if (navigator.userAgent.indexOf("Mobile") != -1 &&
navigator.appVersion.indexOf("Android") == -1) {
ok(false, "Should run the test on Firefox OS (B2G)!");
}
SimpleTest.finish();
}
});
}
SimpleTest.expectAssertions(0, 9);
SimpleTest.waitForExplicitFinish();
if (SpecialPowers.hasPermission("alarms", document)) {
startTests();
} else {
// Add the permission and reload the page so it propogates
SpecialPowers.addPermission("alarms", true, document);
window.location.reload();
}
</script>
</pre>
</body>
</html>

View File

@ -1,70 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
Components.utils.import("resource://gre/modules/AlarmService.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "gTimeService",
"@mozilla.org/time/timeservice;1",
"nsITimeService");
const ALARM_OFFSET = 10000; // 10 seconds.
const CLOCK_OFFSET = 20000; // 20 seconds.
const MANIFEST_URL = "http://dummyurl.com/manifest.webapp";
var alarmDate;
var alarmFired;
function alarmCb() {
alarmFired = true;
};
function run_test() {
do_get_profile();
Services.prefs.setBoolPref("dom.mozAlarms.enabled", true);
run_next_test();
}
/* Tests */
add_test(function test_getAll() {
do_print("= There should not be any alarm =");
AlarmService._db.getAll(MANIFEST_URL, (aAlarms) => {
do_check_eq(aAlarms.length, 0);
run_next_test();
});
});
add_test(function test_addAlarm() {
do_print("= Set alarm =");
alarmDate = Date.now() + ALARM_OFFSET;
AlarmService.add({
date: alarmDate,
manifestURL: MANIFEST_URL
}, alarmCb, run_next_test, do_throw);
});
add_test(function test_alarmNotFired() {
do_print("= The alarm should be in the DB and pending =");
AlarmService._db.getAll(MANIFEST_URL, aAlarms => {
do_check_eq(aAlarms.length, 1, "The alarm is in the DB");
run_next_test();
});
});
add_test(function test_changeSystemClock() {
do_print("= Change system clock =");
gTimeService.set(Date.now() + CLOCK_OFFSET);
run_next_test();
});
add_test(function test_alarmFired() {
do_print("= The alarm should have been fired and removed from the DB =");
do_check_true(alarmFired, "The alarm was fired");
AlarmService._db.getAll(MANIFEST_URL, aAlarms => {
do_check_eq(aAlarms.length, 0, "No alarms in the DB");
run_next_test();
});
});

View File

@ -1,34 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test Non-Permitted Application for Alarm API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
if (SpecialPowers.hasPermission("alarms", document)) {
SpecialPowers.removePermission("alarms", document);
window.location.reload();
} else {
SpecialPowers.pushPrefEnv({"set": [["dom.mozAlarms.enabled", true]]}, function() {
SpecialPowers.removePermission("alarms", document);
ok(!('mozAlarms' in navigator),
"navigator.mozAlarms should not exist without permission");
ok(!('AlarmsManager' in window),
"Interface AlarmsManager should not exist without permission");
SpecialPowers.addPermission("alarms", true, document);
SimpleTest.finish();
});
}
</script>
</pre>
</body>
</html>

View File

@ -1,42 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test Permitted Application for Alarm API</title>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["dom.mozAlarms.enabled", true]]}, function() {
// mozAlarms is installed on all platforms except Android for the moment.
if (navigator.appVersion.indexOf("Android") != -1) {
try {
todo('mozAlarms' in navigator,
"mozAlarms is not allowed on Android for now. TODO Bug 863557.");
} catch (e) {
todo(!e, "('mozAlarms' in navigator) should not throw exceptions once " +
"mozAlarms is installed on Android. TODO Bug 863557. " +
"Caught exception: " + e);
}
} else {
ok('AlarmsManager' in window, "Interface AlarmsManager should exist");
ok('mozAlarms' in navigator, "navigator.mozAlarms should exist");
ok(navigator.mozAlarms instanceof AlarmsManager,
"navigator.mozAlarms should be an instance of AlarmsManager");
}
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

View File

@ -1,118 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test Adding and Removing Alarms with Alarm API</title>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript">
"use strict";
function checkNumberOfAlarms(n, cbk) {
var domRequest;
try {
domRequest = navigator.mozAlarms.getAll();
} catch (e) {
ok(false,
"Unexpected exception trying to get all alarms.");
return cbk();
}
domRequest.onsuccess = function(e) {
ok(e.target.result.length === n, "Correct number of alarms set.");
cbk();
}
}
// Add alarm and then remove it
function testAddRemove() {
var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
var domRequest;
try {
domRequest = navigator.mozAlarms.getAll();
} catch (e) {
ok(false,
"Unexpected exception trying to get all alarms.");
return SimpleTest.finish();
}
domRequest.onsuccess = function(e) {
var initialAlarmsN = e.target.result.length;
var dr;
try {
dr = navigator.mozAlarms.add(tomorrow, "honorTimezone", null);
} catch (e) {
ok(false,
"Unexpected exception trying add alarm.");
return SimpleTest.finish();
}
dr.onsuccess = function(ev) {
var alarmId = ev.target.result;
checkNumberOfAlarms(initialAlarmsN + 1, function() {
navigator.mozAlarms.remove(alarmId);
checkNumberOfAlarms(initialAlarmsN, function() {
SimpleTest.finish();
});
});
}
}
}
function startTests() {
SpecialPowers.pushPrefEnv({
"set": [["dom.mozAlarms.enabled", true]]
}, function() {
var isAllowedToTest = true;
if (navigator.appVersion.indexOf("Android") !== -1) {
ok(true, "mozAlarms is not allowed on Android for now. " +
"TODO Bug 863557.");
isAllowedToTest = false;
} else if (SpecialPowers.wrap(document).nodePrincipal.appStatus ==
SpecialPowers.Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED) {
ok(true, "mozAlarms is not allowed for non-installed apps. " +
"TODO Bug 876981.");
isAllowedToTest = false;
}
if (isAllowedToTest) {
ok(true, "Start to test...");
testAddRemove();
} else {
// A sanity check to make sure we must run tests on Firefox OS (B2G).
if (navigator.userAgent.indexOf("Mobile") != -1 &&
navigator.appVersion.indexOf("Android") == -1) {
ok(false, "Should run the test on Firefox OS (B2G)!");
}
SimpleTest.finish();
}
});
}
SimpleTest.expectAssertions(0, 9);
SimpleTest.waitForExplicitFinish();
if (SpecialPowers.hasPermission("alarms", document)) {
startTests();
} else {
// Add the permission and reload so it's propogated
SpecialPowers.addPermission("alarms", true, document);
window.location.reload();
}
</script>
</pre>
</body>
</html>

View File

@ -1,73 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test data Paramter of Alarm API for Bug 1015540</title>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1015540">Bug 1015540</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript">
"use strict";
// Verify passing a cross-origin object for the data paramter
function testCrossOriginObject() {
var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
var data = document.getElementById('ifr').contentWindow;
try {
navigator.mozAlarms.add(tomorrow, "honorTimezone", data);
ok(false, "Adding alarms for cross-origin objects should be prohibited.");
} catch (e) {
ok(true, "Adding alarms for cross-origin objects is prohibited.");
}
SimpleTest.finish();
}
function startTests() {
SpecialPowers.pushPrefEnv({
"set": [["dom.mozAlarms.enabled", true]]
}, function() {
SpecialPowers.addPermission("alarms", true, document);
var isAllowedToTest = true;
if (navigator.appVersion.indexOf("Android") !== -1) {
ok(true, "mozAlarms is not allowed on Android for now. " +
"TODO Bug 863557.");
isAllowedToTest = false;
} else if (SpecialPowers.wrap(document).nodePrincipal.appStatus ==
SpecialPowers.Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED) {
ok(true, "mozAlarms is not allowed for non-installed apps. " +
"TODO Bug 876981.");
isAllowedToTest = false;
}
if (isAllowedToTest) {
ok(true, "Start to test...");
testCrossOriginObject();
} else {
// A sanity check to make sure we must run tests on Firefox OS (B2G).
if (navigator.userAgent.indexOf("Mobile") != -1 &&
navigator.appVersion.indexOf("Android") == -1) {
ok(false, "Should run the test on Firefox OS (B2G)!");
}
SimpleTest.finish();
}
});
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
<iframe id="ifr" onload="startTests()" src="http://example.org/tests/dom/alarm/test/file_empty.html"></iframe>
</body>
</html>

View File

@ -1,105 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test time alert is fired for Bug 1037079</title>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript">
"use strict";
function registerPage() {
var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('system_message_chrome_script.js'));
gScript.addMessageListener("page-registered", function pageRegisteredHandler() {
gScript.removeMessageListener("page-registered", pageRegisteredHandler);
gScript.destroy();
testFireTimeAlert();
});
gScript.sendAsyncMessage("trigger-register-page",
{ type: "alarm",
manifestURL: window.location.origin + "/manifest.webapp",
pageURL: window.location.href });
}
function testFireTimeAlert() {
var secondsLater = new Date();
secondsLater.setSeconds(secondsLater.getSeconds() + 10);
var domRequest;
try {
// Set system message handler.
navigator.mozSetMessageHandler('alarm', function(message){
ok(true, "Time alert has been fired.");
SimpleTest.finish();
});
domRequest = navigator.mozAlarms.add(secondsLater, "honorTimezone",
{type: "timer"});
} catch (e) {
ok(false, "Unexpected exception trying to set time alert.");
return SimpleTest.finish();
}
domRequest.onsuccess = function(e) {
ok(true, "Set time alert. Waiting to be fired.");
};
domRequest.onerror = function(e) {
ok(false, "Unable to set time alert.");
SimpleTest.finish();
};
}
function startTests() {
SpecialPowers.pushPrefEnv({
"set": [["dom.mozAlarms.enabled", true]]
}, function() {
var isAllowedToTest = true;
if (navigator.appVersion.indexOf("Android") !== -1) {
ok(true, "mozAlarms is not allowed on Android for now. " +
"TODO Bug 863557.");
isAllowedToTest = false;
} else if (SpecialPowers.wrap(document).nodePrincipal.appStatus ==
SpecialPowers.Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED) {
ok(true, "mozAlarms is not allowed for non-installed apps. " +
"TODO Bug 876981.");
isAllowedToTest = false;
}
if (isAllowedToTest) {
ok(true, "Start to test...");
registerPage();
} else {
// A sanity check to make sure we must run tests on Firefox OS (B2G).
if (navigator.userAgent.indexOf("Mobile") != -1 &&
navigator.appVersion.indexOf("Android") == -1) {
ok(false, "Should run the test on Firefox OS (B2G)!");
}
SimpleTest.finish();
}
});
}
SimpleTest.expectAssertions(0, 9);
SimpleTest.waitForExplicitFinish();
if (SpecialPowers.hasPermission("alarms", document)) {
startTests();
} else {
// Add the permissions and reload so they propogate
SpecialPowers.addPermission("alarms", true, document);
window.location.reload();
}
</script>
</pre>
</body>
</html>

View File

@ -1,97 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test time alert is fired for Bug 1090896</title>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript">
"use strict";
function registerPage() {
var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('system_message_chrome_script.js'));
gScript.addMessageListener("page-registered", function pageRegisteredHandler() {
gScript.removeMessageListener("page-registered", pageRegisteredHandler);
gScript.destroy();
testFireTimeAlertWithNoData();
});
gScript.sendAsyncMessage("trigger-register-page",
{ type: "alarm",
manifestURL: window.location.origin + "/manifest.webapp",
pageURL: window.location.href });
}
function testFireTimeAlertWithNoData() {
var secondsLater = new Date();
secondsLater.setSeconds(secondsLater.getSeconds() + 1);
var domRequest;
try {
// Set system message handler.
navigator.mozSetMessageHandler('alarm', function(message){
ok(true, "Time alert has been fired.");
SimpleTest.finish();
});
domRequest = navigator.mozAlarms.add(secondsLater, "honorTimezone");
} catch (e) {
ok(false, "Unexpected exception trying to set time alert. " + e);
return SimpleTest.finish();
}
domRequest.onsuccess = function(e) {
ok(true, "Set time alert. Waiting to be fired.");
};
domRequest.onerror = function(e) {
ok(false, "Unable to set time alert.");
SimpleTest.finish();
};
}
function startTests() {
SpecialPowers.pushPrefEnv({
"set": [["dom.mozAlarms.enabled", true]]
}, function() {
var isAllowedToTest = true;
if (navigator.appVersion.indexOf("Android") !== -1) {
ok(true, "mozAlarms is not allowed on Android for now. " +
"TODO Bug 863557.");
isAllowedToTest = false;
} else if (SpecialPowers.wrap(document).nodePrincipal.appStatus ==
SpecialPowers.Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED) {
ok(true, "mozAlarms is not allowed for non-installed apps. " +
"TODO Bug 876981.");
isAllowedToTest = false;
}
if (isAllowedToTest) {
ok(true, "Start to test...");
registerPage();
} else {
// A sanity check to make sure we must run tests on Firefox OS (B2G).
if (navigator.userAgent.indexOf("Mobile") != -1 &&
navigator.appVersion.indexOf("Android") == -1) {
ok(false, "Should run the test on Firefox OS (B2G)!");
}
SimpleTest.finish();
}
});
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPermissions([{'type': 'alarms', 'allow': true, 'context': document}], startTests);
</script>
</pre>
</body>
</html>

View File

@ -1,7 +0,0 @@
[DEFAULT]
head =
tail =
[test_alarm_change_system_clock.js]
# This test fails on the ICS emulator. We can enable it once bug 1090359 is fixed.
skip-if = 1

View File

@ -226,13 +226,13 @@ Animation::SetTimeline(AnimationTimeline* aTimeline)
void
Animation::SetTimelineNoUpdate(AnimationTimeline* aTimeline)
{
RefPtr<AnimationTimeline> oldTimeline = mTimeline;
if (mTimeline == aTimeline) {
return;
}
if (mTimeline) {
mTimeline->RemoveAnimation(this);
RefPtr<AnimationTimeline> oldTimeline = mTimeline;
if (oldTimeline) {
oldTimeline->RemoveAnimation(this);
}
mTimeline = aTimeline;

View File

@ -207,6 +207,7 @@ void
NodeInfo::DeleteCycleCollectable()
{
RefPtr<nsNodeInfoManager> kungFuDeathGrip = mOwnerManager;
mozilla::Unused << kungFuDeathGrip; // Just keeping value alive for longer than this
delete this;
}

View File

@ -77,7 +77,7 @@ TextInputProcessor::~TextInputProcessor()
if (NS_SUCCEEDED(IsValidStateForComposition())) {
RefPtr<TextEventDispatcher> kungFuDeathGrip(mDispatcher);
nsEventStatus status = nsEventStatus_eIgnore;
mDispatcher->CommitComposition(status, &EmptyString());
kungFuDeathGrip->CommitComposition(status, &EmptyString());
}
}
}
@ -374,7 +374,7 @@ TextInputProcessor::StartComposition(nsIDOMKeyEvent* aDOMKeyEvent,
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
*aSucceeded = false;
RefPtr<TextEventDispatcher> kungfuDeathGrip(mDispatcher);
RefPtr<TextEventDispatcher> kungFuDeathGrip(mDispatcher);
WidgetKeyboardEvent* keyboardEvent;
nsresult rv =
@ -393,9 +393,9 @@ TextInputProcessor::StartComposition(nsIDOMKeyEvent* aDOMKeyEvent,
if (dispatcherResult.mDoDefault) {
nsEventStatus status = nsEventStatus_eIgnore;
rv = mDispatcher->StartComposition(status);
rv = kungFuDeathGrip->StartComposition(status);
*aSucceeded = status != nsEventStatus_eConsumeNoDefault &&
mDispatcher && mDispatcher->IsComposing();
kungFuDeathGrip && kungFuDeathGrip->IsComposing();
}
MaybeDispatchKeyupForComposition(keyboardEvent, aKeyFlags);
@ -410,12 +410,12 @@ NS_IMETHODIMP
TextInputProcessor::SetPendingCompositionString(const nsAString& aString)
{
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
RefPtr<TextEventDispatcher> kungfuDeathGrip(mDispatcher);
RefPtr<TextEventDispatcher> kungFuDeathGrip(mDispatcher);
nsresult rv = IsValidStateForComposition();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return mDispatcher->SetPendingCompositionString(aString);
return kungFuDeathGrip->SetPendingCompositionString(aString);
}
NS_IMETHODIMP
@ -423,7 +423,7 @@ TextInputProcessor::AppendClauseToPendingComposition(uint32_t aLength,
uint32_t aAttribute)
{
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
RefPtr<TextEventDispatcher> kungfuDeathGrip(mDispatcher);
RefPtr<TextEventDispatcher> kungFuDeathGrip(mDispatcher);
TextRangeType textRangeType;
switch (aAttribute) {
case ATTR_RAW_CLAUSE:
@ -439,19 +439,19 @@ TextInputProcessor::AppendClauseToPendingComposition(uint32_t aLength,
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return mDispatcher->AppendClauseToPendingComposition(aLength, textRangeType);
return kungFuDeathGrip->AppendClauseToPendingComposition(aLength, textRangeType);
}
NS_IMETHODIMP
TextInputProcessor::SetCaretInPendingComposition(uint32_t aOffset)
{
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
RefPtr<TextEventDispatcher> kungfuDeathGrip(mDispatcher);
RefPtr<TextEventDispatcher> kungFuDeathGrip(mDispatcher);
nsresult rv = IsValidStateForComposition();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return mDispatcher->SetCaretInPendingComposition(aOffset, 0);
return kungFuDeathGrip->SetCaretInPendingComposition(aOffset, 0);
}
NS_IMETHODIMP
@ -468,7 +468,7 @@ TextInputProcessor::FlushPendingComposition(nsIDOMKeyEvent* aDOMKeyEvent,
AutoPendingCompositionResetter resetter(this);
*aSucceeded = false;
RefPtr<TextEventDispatcher> kungfuDeathGrip(mDispatcher);
RefPtr<TextEventDispatcher> kungFuDeathGrip(mDispatcher);
bool wasComposing = IsComposing();
WidgetKeyboardEvent* keyboardEvent;
@ -494,7 +494,7 @@ TextInputProcessor::FlushPendingComposition(nsIDOMKeyEvent* aDOMKeyEvent,
return NS_OK;
}
nsEventStatus status = nsEventStatus_eIgnore;
rv = mDispatcher->FlushPendingComposition(status);
rv = kungFuDeathGrip->FlushPendingComposition(status);
*aSucceeded = status != nsEventStatus_eConsumeNoDefault;
}
@ -556,7 +556,7 @@ TextInputProcessor::CommitCompositionInternal(
if (aSucceeded) {
*aSucceeded = false;
}
RefPtr<TextEventDispatcher> kungfuDeathGrip(mDispatcher);
RefPtr<TextEventDispatcher> kungFuDeathGrip(mDispatcher);
bool wasComposing = IsComposing();
EventDispatcherResult dispatcherResult =
@ -575,7 +575,7 @@ TextInputProcessor::CommitCompositionInternal(
return NS_OK;
}
nsEventStatus status = nsEventStatus_eIgnore;
rv = mDispatcher->CommitComposition(status, aCommitString);
rv = kungFuDeathGrip->CommitComposition(status, aCommitString);
if (aSucceeded) {
*aSucceeded = status != nsEventStatus_eConsumeNoDefault;
}
@ -612,7 +612,7 @@ TextInputProcessor::CancelCompositionInternal(
const WidgetKeyboardEvent* aKeyboardEvent,
uint32_t aKeyFlags)
{
RefPtr<TextEventDispatcher> kungfuDeathGrip(mDispatcher);
RefPtr<TextEventDispatcher> kungFuDeathGrip(mDispatcher);
EventDispatcherResult dispatcherResult =
MaybeDispatchKeydownForComposition(aKeyboardEvent, aKeyFlags);
@ -622,7 +622,7 @@ TextInputProcessor::CancelCompositionInternal(
}
nsEventStatus status = nsEventStatus_eIgnore;
nsresult rv = mDispatcher->CommitComposition(status, &EmptyString());
nsresult rv = kungFuDeathGrip->CommitComposition(status, &EmptyString());
MaybeDispatchKeyupForComposition(aKeyboardEvent, aKeyFlags);
@ -835,7 +835,7 @@ TextInputProcessor::KeydownInternal(const WidgetKeyboardEvent& aKeyboardEvent,
}
keyEvent.mModifiers = GetActiveModifiers();
RefPtr<TextEventDispatcher> kungfuDeathGrip(mDispatcher);
RefPtr<TextEventDispatcher> kungFuDeathGrip(mDispatcher);
rv = IsValidStateForComposition();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@ -843,7 +843,7 @@ TextInputProcessor::KeydownInternal(const WidgetKeyboardEvent& aKeyboardEvent,
nsEventStatus status = aConsumedFlags ? nsEventStatus_eConsumeNoDefault :
nsEventStatus_eIgnore;
if (!mDispatcher->DispatchKeyboardEvent(eKeyDown, keyEvent, status)) {
if (!kungFuDeathGrip->DispatchKeyboardEvent(eKeyDown, keyEvent, status)) {
// If keydown event isn't dispatched, we don't need to dispatch keypress
// events.
return NS_OK;
@ -854,7 +854,7 @@ TextInputProcessor::KeydownInternal(const WidgetKeyboardEvent& aKeyboardEvent,
KEYEVENT_NOT_CONSUMED;
if (aAllowToDispatchKeypress &&
mDispatcher->MaybeDispatchKeypressEvents(keyEvent, status)) {
kungFuDeathGrip->MaybeDispatchKeypressEvents(keyEvent, status)) {
aConsumedFlags |=
(status == nsEventStatus_eConsumeNoDefault) ? KEYPRESS_IS_CONSUMED :
KEYEVENT_NOT_CONSUMED;
@ -915,7 +915,7 @@ TextInputProcessor::KeyupInternal(const WidgetKeyboardEvent& aKeyboardEvent,
}
keyEvent.mModifiers = GetActiveModifiers();
RefPtr<TextEventDispatcher> kungfuDeathGrip(mDispatcher);
RefPtr<TextEventDispatcher> kungFuDeathGrip(mDispatcher);
rv = IsValidStateForComposition();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@ -923,7 +923,7 @@ TextInputProcessor::KeyupInternal(const WidgetKeyboardEvent& aKeyboardEvent,
nsEventStatus status = aDoDefault ? nsEventStatus_eIgnore :
nsEventStatus_eConsumeNoDefault;
mDispatcher->DispatchKeyboardEvent(eKeyUp, keyEvent, status);
kungFuDeathGrip->DispatchKeyboardEvent(eKeyUp, keyEvent, status);
aDoDefault = (status != nsEventStatus_eConsumeNoDefault);
return NS_OK;
}

View File

@ -1265,18 +1265,18 @@ WebSocket::ConstructorCommon(const GlobalObject& aGlobal,
}
RefPtr<WebSocket> webSocket = new WebSocket(ownerWindow);
RefPtr<WebSocketImpl> kungfuDeathGrip = webSocket->mImpl;
RefPtr<WebSocketImpl> webSocketImpl = webSocket->mImpl;
bool connectionFailed = true;
if (NS_IsMainThread()) {
webSocket->mImpl->Init(aGlobal.Context(), principal, !!aTransportProvider,
aUrl, protocolArray, EmptyCString(),
0, 0, aRv, &connectionFailed);
webSocketImpl->Init(aGlobal.Context(), principal, !!aTransportProvider,
aUrl, protocolArray, EmptyCString(),
0, 0, aRv, &connectionFailed);
} else {
// In workers we have to keep the worker alive using a workerHolder in order
// to dispatch messages correctly.
if (!webSocket->mImpl->RegisterWorkerHolder()) {
if (!webSocketImpl->RegisterWorkerHolder()) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
@ -1289,7 +1289,7 @@ WebSocket::ConstructorCommon(const GlobalObject& aGlobal,
}
RefPtr<InitRunnable> runnable =
new InitRunnable(webSocket->mImpl, !!aTransportProvider, aUrl,
new InitRunnable(webSocketImpl, !!aTransportProvider, aUrl,
protocolArray, nsDependentCString(file.get()), lineno,
column, aRv, &connectionFailed);
runnable->Dispatch(aRv);

View File

@ -545,7 +545,8 @@ static nsresult AppendDOMNode(nsITransferable *aTransferable,
// Note that XHTML is not counted as HTML here, because we can't copy it
// properly (all the copy code for non-plaintext assumes using HTML
// serializers and parsers is OK, and those mess up XHTML).
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(document, &rv);
DebugOnly<nsCOMPtr<nsIHTMLDocument>> htmlDoc =
nsCOMPtr<nsIHTMLDocument>(do_QueryInterface(document, &rv));
NS_ENSURE_SUCCESS(rv, NS_OK);
NS_ENSURE_TRUE(document->IsHTMLDocument(), NS_OK);

View File

@ -260,7 +260,7 @@ nsDOMAttributeMap::SetNamedItemNS(Attr& aAttr, ErrorResult& aError)
nsresult rv;
if (mContent->OwnerDoc() != aAttr.OwnerDoc()) {
nsCOMPtr<nsINode> adoptedNode =
DebugOnly<void*> adoptedNode =
mContent->OwnerDoc()->AdoptNode(aAttr, aError);
if (aError.Failed()) {
return nullptr;

View File

@ -4713,9 +4713,9 @@ nsDocument::GetWindowInternal() const
nsCOMPtr<nsPIDOMWindowOuter> win;
if (mRemovedFromDocShell) {
// The docshell returns the outer window we are done.
nsCOMPtr<nsIDocShell> kungfuDeathGrip(mDocumentContainer);
if (mDocumentContainer) {
win = mDocumentContainer->GetWindow();
nsCOMPtr<nsIDocShell> kungFuDeathGrip(mDocumentContainer);
if (kungFuDeathGrip) {
win = kungFuDeathGrip->GetWindow();
}
} else {
if (nsCOMPtr<nsPIDOMWindowInner> inner = do_QueryInterface(mScriptGlobalObject)) {

View File

@ -1060,11 +1060,11 @@ nsFrameLoader::SwapWithOtherRemoteLoader(nsFrameLoader* aOther,
RefPtr<nsFrameMessageManager> ourMessageManager = mMessageManager;
RefPtr<nsFrameMessageManager> otherMessageManager = aOther->mMessageManager;
// Swap and setup things in parent message managers.
if (mMessageManager) {
mMessageManager->SetCallback(aOther);
if (ourMessageManager) {
ourMessageManager->SetCallback(aOther);
}
if (aOther->mMessageManager) {
aOther->mMessageManager->SetCallback(this);
if (otherMessageManager) {
otherMessageManager->SetCallback(this);
}
mMessageManager.swap(aOther->mMessageManager);
@ -2759,7 +2759,9 @@ nsFrameLoader::CreateStaticClone(nsIFrameLoader* aDest)
dest->MaybeCreateDocShell();
NS_ENSURE_STATE(dest->mDocShell);
nsCOMPtr<nsIDocument> dummy = dest->mDocShell->GetDocument();
nsCOMPtr<nsIDocument> kungFuDeathGrip = dest->mDocShell->GetDocument();
Unused << kungFuDeathGrip;
nsCOMPtr<nsIContentViewer> viewer;
dest->mDocShell->GetContentViewer(getter_AddRefs(viewer));
NS_ENSURE_STATE(viewer);

View File

@ -1313,12 +1313,16 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
}
}
}
RefPtr<nsFrameMessageManager> kungfuDeathGrip = mParentManager;
return mParentManager ? mParentManager->ReceiveMessage(aTarget, aTargetFrameLoader,
aTargetClosed, aMessage,
aIsSync, aCloneData,
aCpows, aPrincipal,
aRetVal) : NS_OK;
RefPtr<nsFrameMessageManager> kungFuDeathGrip = mParentManager;
if (kungFuDeathGrip) {
return kungFuDeathGrip->ReceiveMessage(aTarget, aTargetFrameLoader,
aTargetClosed, aMessage,
aIsSync, aCloneData,
aCpows, aPrincipal,
aRetVal);
}
return NS_OK;
}
void

View File

@ -449,7 +449,8 @@ nsGlobalWindow::DOMMinTimeoutValue() const {
if (mIsClosed) { \
return err_rval; \
} \
nsCOMPtr<nsIDocument> doc = GetDoc(); \
nsCOMPtr<nsIDocument> kungFuDeathGrip = GetDoc(); \
::mozilla::Unused << kungFuDeathGrip; \
if (!mInnerWindow) { \
return err_rval; \
} \
@ -2158,10 +2159,12 @@ nsGlobalWindow::SetInitialPrincipalToSubject()
// First, grab the subject principal.
nsCOMPtr<nsIPrincipal> newWindowPrincipal = nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller();
// Now, if we're about to use the system principal or an nsExpandedPrincipal,
// make sure we're not using it for a content docshell.
if (nsContentUtils::IsSystemOrExpandedPrincipal(newWindowPrincipal) &&
GetDocShell()->ItemType() != nsIDocShellTreeItem::typeChrome) {
// We should never create windows with an expanded principal.
// If we have a system principal, make sure we're not using it for a content
// docshell.
if (nsContentUtils::IsExpandedPrincipal(newWindowPrincipal) ||
(nsContentUtils::IsSystemPrincipal(newWindowPrincipal) &&
GetDocShell()->ItemType() != nsIDocShellTreeItem::typeChrome)) {
newWindowPrincipal = nullptr;
}
@ -2868,7 +2871,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
// Initialize DOM classes etc on the inner window.
JS::Rooted<JSObject*> obj(cx, newInnerGlobal);
rv = mContext->InitClasses(obj);
rv = kungFuDeathGrip->InitClasses(obj);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -2891,7 +2894,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
}
nsJSContext::PokeGC(JS::gcreason::SET_NEW_DOCUMENT);
mContext->DidInitializeContext();
kungFuDeathGrip->DidInitializeContext();
// We wait to fire the debugger hook until the window is all set up and hooked
// up with the outer. See bug 969156.
@ -3434,7 +3437,10 @@ nsGlobalWindow::PostHandleEvent(EventChainPostVisitor& aVisitor)
function under some circumstances (events that destroy the window)
without this addref. */
nsCOMPtr<nsIDOMEventTarget> kungFuDeathGrip1(mChromeEventHandler);
mozilla::Unused << kungFuDeathGrip1; // These aren't referred to through the function
nsCOMPtr<nsIScriptContext> kungFuDeathGrip2(GetContextInternal());
mozilla::Unused << kungFuDeathGrip2; // These aren't referred to through the function
if (aVisitor.mEvent->mMessage == eResize) {
mIsHandlingResizeEvent = false;
@ -3604,6 +3610,7 @@ nsPIDOMWindow<T>::MaybeCreateDoc()
// don't have to explicitly set the member variable because the docshell
// has already called SetNewDocument().
nsCOMPtr<nsIDocument> document = docShell->GetDocument();
Unused << document;
}
}
@ -11866,6 +11873,7 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
// Force document creation.
nsCOMPtr<nsIDocument> doc = (*aReturn)->GetDoc();
Unused << doc;
}
}

View File

@ -2186,11 +2186,15 @@ DOMGCSliceCallback(JSContext* aCx, JS::GCProgress aProgress, const JS::GCDescrip
}
if (sPostGCEventsToConsole) {
nsString gcstats;
NS_NAMED_LITERAL_STRING(kFmt, "[%s] ");
nsString prefix, gcstats;
gcstats.Adopt(aDesc.formatSliceMessage(aCx));
prefix.Adopt(nsTextFormatter::smprintf(kFmt.get(),
ProcessNameForCollectorLog()));
nsString msg = prefix + gcstats;
nsCOMPtr<nsIConsoleService> cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (cs) {
cs->LogStringMessage(gcstats.get());
cs->LogStringMessage(msg.get());
}
}

View File

@ -3038,6 +3038,7 @@ nsObjectLoadingContent::SyncStartPluginInstance()
}
nsCOMPtr<nsIURI> kungFuURIGrip(mURI);
mozilla::Unused << kungFuURIGrip; // This URI is not referred to within this function
nsCString contentType(mContentType);
return InstantiatePluginInstance();
}

View File

@ -25,6 +25,8 @@
#include "nsIObserver.h"
#include "nsIObserverService.h"
#include "mozilla/Unused.h"
#define FILTER_NO_SMS_GSM 0x01
#define FILTER_NO_SMS_CDMA 0x02
#define FILTER_NO_EMAIL 0x04

View File

@ -24,6 +24,8 @@
#include "nsIObserverService.h"
#include "nsNetCID.h"
#include "mozilla/Unused.h"
USING_BLUETOOTH_NAMESPACE
using namespace mozilla;
using namespace mozilla::dom;

View File

@ -17,6 +17,7 @@
#include "nsIUUIDGenerator.h"
#include "nsServiceManagerUtils.h"
#include "nsXULAppAPI.h"
#include "mozilla/Unused.h"
BEGIN_BLUETOOTH_NAMESPACE

View File

@ -388,7 +388,7 @@ TestGonkCameraHardware::Init()
DebugOnly<nsresult> rv = WaitWhileRunningOnMainThread(new Delegate(this));
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "WaitWhileRunningOnMainThread failed");
return rv;
return NS_OK;
}
int

View File

@ -2000,7 +2000,7 @@ Console::StartTimer(JSContext* aCx, const JS::Value& aName,
return false;
}
DOMHighResTimeStamp entry;
DOMHighResTimeStamp entry = 0;
if (!mTimerRegistry.Get(label, &entry)) {
mTimerRegistry.Put(label, aTimestamp);
} else {
@ -2063,7 +2063,7 @@ Console::StopTimer(JSContext* aCx, const JS::Value& aName,
return false;
}
DOMHighResTimeStamp entry;
DOMHighResTimeStamp entry = 0;
if (NS_WARN_IF(!mTimerRegistry.Get(key, &entry))) {
return false;
}

View File

@ -323,7 +323,7 @@ IMEStateManager::OnRemoveContent(nsPresContext* aPresContext,
// is called during the content being removed. Then, the native
// composition events which are caused by following APIs are ignored due
// to unsafe to run script (in PresShell::HandleEvent()).
nsCOMPtr<nsIWidget> widget = aPresContext->GetRootWidget();
DebugOnly<void*> widget = aPresContext->GetRootWidget();
MOZ_ASSERT(widget, "Why is there no widget?");
nsresult rv =
compositionInContent->NotifyIME(REQUEST_TO_CANCEL_COMPOSITION);
@ -1601,8 +1601,8 @@ IMEStateManager::CreateIMEContentObserver(nsIEditor* aEditor)
// IMEContentObserver::Init() might create another IMEContentObserver
// instance. So, sActiveIMEContentObserver would be replaced with new one.
// We should hold the current instance here.
RefPtr<IMEContentObserver> kungFuDeathGrip(sActiveIMEContentObserver);
sActiveIMEContentObserver->Init(widget, sPresContext, sContent, aEditor);
RefPtr<IMEContentObserver> activeIMEContentObserver(sActiveIMEContentObserver);
activeIMEContentObserver->Init(widget, sPresContext, sContent, aEditor);
}
// static

View File

@ -1049,7 +1049,7 @@ FetchBody<Derived>::ContinueConsumeBody(nsresult aStatus, uint32_t aResultLength
MOZ_ASSERT(mConsumePromise);
RefPtr<Promise> localPromise = mConsumePromise.forget();
RefPtr<Derived> kungfuDeathGrip = DerivedClass();
RefPtr<Derived> derivedClass = DerivedClass();
ReleaseObject();
if (NS_WARN_IF(NS_FAILED(aStatus))) {
@ -1098,7 +1098,7 @@ FetchBody<Derived>::ContinueConsumeBody(nsresult aStatus, uint32_t aResultLength
MOZ_ASSERT(aResult);
AutoJSAPI jsapi;
if (!jsapi.Init(DerivedClass()->GetParentObject())) {
if (!jsapi.Init(derivedClass->GetParentObject())) {
localPromise->MaybeReject(NS_ERROR_UNEXPECTED);
return;
}
@ -1124,7 +1124,7 @@ FetchBody<Derived>::ContinueConsumeBody(nsresult aStatus, uint32_t aResultLength
}
case CONSUME_BLOB: {
RefPtr<dom::Blob> blob = BodyUtil::ConsumeBlob(
DerivedClass()->GetParentObject(), NS_ConvertUTF8toUTF16(mMimeType),
derivedClass->GetParentObject(), NS_ConvertUTF8toUTF16(mMimeType),
aResultLength, aResult, error);
if (!error.Failed()) {
localPromise->MaybeResolve(blob);
@ -1139,7 +1139,7 @@ FetchBody<Derived>::ContinueConsumeBody(nsresult aStatus, uint32_t aResultLength
autoFree.Reset();
RefPtr<dom::FormData> fd = BodyUtil::ConsumeFormData(
DerivedClass()->GetParentObject(),
derivedClass->GetParentObject(),
mMimeType, data, error);
if (!error.Failed()) {
localPromise->MaybeResolve(fd);

View File

@ -171,16 +171,6 @@ FlyWebPublishedServerImpl::FlyWebPublishedServerImpl(nsPIDOMWindowInner* aOwner,
, mHttpServer(new HttpServer())
{
LOG_I("FlyWebPublishedServerImpl::FlyWebPublishedServerImpl(%p)", this);
}
void
FlyWebPublishedServerImpl::PermissionGranted(bool aGranted)
{
LOG_I("FlyWebPublishedServerImpl::PermissionGranted(%b)", aGranted);
if (!aGranted) {
PublishedServerStarted(NS_ERROR_FAILURE);
return;
}
mHttpServer->Init(-1, Preferences::GetBool("flyweb.use-tls", false), this);
}
@ -262,37 +252,25 @@ FlyWebPublishedServerChild::FlyWebPublishedServerChild(nsPIDOMWindowInner* aOwne
const nsAString& aName,
const FlyWebPublishOptions& aOptions)
: FlyWebPublishedServer(aOwner, aName, aOptions)
, mActorExists(false)
, mActorDestroyed(false)
{
LOG_I("FlyWebPublishedServerChild::FlyWebPublishedServerChild(%p)", this);
ContentChild::GetSingleton()->
SendPFlyWebPublishedServerConstructor(this,
PromiseFlatString(aName),
aOptions);
// The matching release happens when the actor is destroyed, in
// ContentChild::DeallocPFlyWebPublishedServerChild
NS_ADDREF_THIS();
}
void
FlyWebPublishedServerChild::PermissionGranted(bool aGranted)
{
if (!aGranted) {
PublishedServerStarted(NS_ERROR_FAILURE);
return;
}
mActorExists = true;
FlyWebPublishOptions options;
options.mUiUrl = mUiUrl;
// Proceed with initialization.
ContentChild::GetSingleton()->
SendPFlyWebPublishedServerConstructor(this, mName, options);
}
bool
FlyWebPublishedServerChild::RecvServerReady(const nsresult& aStatus)
{
LOG_I("FlyWebPublishedServerChild::RecvServerReady(%p)", this);
MOZ_ASSERT(mActorExists);
MOZ_ASSERT(!mActorDestroyed);
PublishedServerStarted(aStatus);
return true;
@ -302,7 +280,7 @@ bool
FlyWebPublishedServerChild::RecvServerClose()
{
LOG_I("FlyWebPublishedServerChild::RecvServerClose(%p)", this);
MOZ_ASSERT(mActorExists);
MOZ_ASSERT(!mActorDestroyed);
Close();
@ -314,7 +292,7 @@ FlyWebPublishedServerChild::RecvFetchRequest(const IPCInternalRequest& aRequest,
const uint64_t& aRequestId)
{
LOG_I("FlyWebPublishedServerChild::RecvFetchRequest(%p)", this);
MOZ_ASSERT(mActorExists);
MOZ_ASSERT(!mActorDestroyed);
RefPtr<InternalRequest> request = new InternalRequest(aRequest);
mPendingRequests.Put(request, aRequestId);
@ -329,7 +307,7 @@ FlyWebPublishedServerChild::RecvWebSocketRequest(const IPCInternalRequest& aRequ
PTransportProviderChild* aProvider)
{
LOG_I("FlyWebPublishedServerChild::RecvWebSocketRequest(%p)", this);
MOZ_ASSERT(mActorExists);
MOZ_ASSERT(!mActorDestroyed);
RefPtr<InternalRequest> request = new InternalRequest(aRequest);
mPendingRequests.Put(request, aRequestId);
@ -349,7 +327,7 @@ FlyWebPublishedServerChild::ActorDestroy(ActorDestroyReason aWhy)
{
LOG_I("FlyWebPublishedServerChild::ActorDestroy(%p)", this);
mActorExists = false;
mActorDestroyed = true;
}
void
@ -358,7 +336,7 @@ FlyWebPublishedServerChild::OnFetchResponse(InternalRequest* aRequest,
{
LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p)", this);
if (!mActorExists) {
if (mActorDestroyed) {
LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p) - No actor!", this);
return;
}
@ -383,7 +361,7 @@ FlyWebPublishedServerChild::OnWebSocketAcceptInternal(InternalRequest* aRequest,
{
LOG_I("FlyWebPublishedServerChild::OnWebSocketAcceptInternal(%p)", this);
if (!mActorExists) {
if (mActorDestroyed) {
LOG_I("FlyWebPublishedServerChild::OnWebSocketAcceptInternal(%p) - No actor!", this);
return nullptr;
}
@ -422,7 +400,7 @@ FlyWebPublishedServerChild::OnWebSocketResponse(InternalRequest* aRequest,
{
LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p)", this);
if (!mActorExists) {
if (mActorDestroyed) {
LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p) - No actor!", this);
return;
}
@ -450,7 +428,7 @@ FlyWebPublishedServerChild::Close()
FlyWebPublishedServer::Close();
if (mActorExists) {
if (!mActorDestroyed) {
LOG_I("FlyWebPublishedServerChild::Close - sending __delete__ (%p)", this);
Send__delete__(this);

View File

@ -57,8 +57,6 @@ public:
aUiUrl = mUiUrl;
}
virtual void PermissionGranted(bool aGranted) = 0;
virtual void OnFetchResponse(InternalRequest* aRequest,
InternalResponse* aResponse) = 0;
already_AddRefed<WebSocket>

View File

@ -50,7 +50,6 @@ public:
}
}
virtual void PermissionGranted(bool aGranted) override;
virtual void OnFetchResponse(InternalRequest* aRequest,
InternalResponse* aResponse) override;
virtual void OnWebSocketResponse(InternalRequest* aConnectRequest,
@ -99,7 +98,6 @@ public:
const nsAString& aName,
const FlyWebPublishOptions& aOptions);
virtual void PermissionGranted(bool aGranted) override;
virtual bool RecvServerReady(const nsresult& aStatus) override;
virtual bool RecvServerClose() override;
virtual bool RecvFetchRequest(const IPCInternalRequest& aRequest,
@ -127,7 +125,7 @@ private:
nsDataHashtable<nsRefPtrHashKey<InternalRequest>, uint64_t> mPendingRequests;
nsRefPtrHashtable<nsUint64HashKey, TransportProviderChild>
mPendingTransportProviders;
bool mActorExists;
bool mActorDestroyed;
};
class FlyWebPublishedServerParent final : public PFlyWebPublishedServerParent

View File

@ -9,7 +9,6 @@
#include "mozilla/ScopeExit.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/FlyWebPublishedServerIPC.h"
#include "mozilla/AddonPathService.h"
#include "nsISocketTransportService.h"
#include "mdns/libmdns/nsDNSServiceInfo.h"
#include "nsIUUIDGenerator.h"
@ -19,7 +18,6 @@
#include "mozilla/dom/FlyWebDiscoveryManagerBinding.h"
#include "prnetdb.h"
#include "DNS.h"
#include "nsContentPermissionHelper.h"
#include "nsSocketTransportService2.h"
#include "nsSocketTransport2.h"
#include "nsHashPropertyBag.h"
@ -36,123 +34,11 @@ struct FlyWebPublishOptions;
static LazyLogModule gFlyWebServiceLog("FlyWebService");
#undef LOG_I
#define LOG_I(...) MOZ_LOG(mozilla::dom::gFlyWebServiceLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
#undef LOG_E
#define LOG_E(...) MOZ_LOG(mozilla::dom::gFlyWebServiceLog, mozilla::LogLevel::Error, (__VA_ARGS__))
#undef LOG_TEST_I
#define LOG_TEST_I(...) MOZ_LOG_TEST(mozilla::dom::gFlyWebServiceLog, mozilla::LogLevel::Debug)
class FlyWebPublishServerPermissionCheck final
: public nsIContentPermissionRequest
, public nsIRunnable
{
public:
NS_DECL_ISUPPORTS
FlyWebPublishServerPermissionCheck(const nsCString& aServiceName, uint64_t aWindowID,
FlyWebPublishedServer* aServer)
: mServiceName(aServiceName)
, mWindowID(aWindowID)
, mServer(aServer)
{}
uint64_t WindowID() const
{
return mWindowID;
}
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
nsGlobalWindow* globalWindow = nsGlobalWindow::GetInnerWindowWithId(mWindowID);
if (!globalWindow) {
return Cancel();
}
mWindow = globalWindow->AsInner();
if (NS_WARN_IF(!mWindow)) {
return Cancel();
}
nsCOMPtr<nsIDocument> doc = mWindow->GetDoc();
if (NS_WARN_IF(!doc)) {
return Cancel();
}
mPrincipal = doc->NodePrincipal();
MOZ_ASSERT(mPrincipal);
mRequester = new nsContentPermissionRequester(mWindow);
return nsContentPermissionUtils::AskPermission(this, mWindow);
}
NS_IMETHOD Cancel() override
{
Resolve(false);
return NS_OK;
}
NS_IMETHOD Allow(JS::HandleValue aChoices) override
{
MOZ_ASSERT(aChoices.isUndefined());
Resolve(true);
return NS_OK;
}
NS_IMETHOD GetTypes(nsIArray** aTypes) override
{
nsTArray<nsString> emptyOptions;
return nsContentPermissionUtils::CreatePermissionArray(NS_LITERAL_CSTRING("flyweb-publish-server"),
NS_LITERAL_CSTRING("unused"), emptyOptions, aTypes);
}
NS_IMETHOD GetRequester(nsIContentPermissionRequester** aRequester) override
{
NS_ENSURE_ARG_POINTER(aRequester);
nsCOMPtr<nsIContentPermissionRequester> requester = mRequester;
requester.forget(aRequester);
return NS_OK;
}
NS_IMETHOD GetPrincipal(nsIPrincipal** aRequestingPrincipal) override
{
NS_IF_ADDREF(*aRequestingPrincipal = mPrincipal);
return NS_OK;
}
NS_IMETHOD GetWindow(mozIDOMWindow** aRequestingWindow) override
{
NS_IF_ADDREF(*aRequestingWindow = mWindow);
return NS_OK;
}
NS_IMETHOD GetElement(nsIDOMElement** aRequestingElement) override
{
*aRequestingElement = nullptr;
return NS_OK;
}
private:
void Resolve(bool aResolve)
{
mServer->PermissionGranted(aResolve);
}
virtual ~FlyWebPublishServerPermissionCheck() = default;
nsCString mServiceName;
uint64_t mWindowID;
RefPtr<FlyWebPublishedServer> mServer;
nsCOMPtr<nsPIDOMWindowInner> mWindow;
nsCOMPtr<nsIPrincipal> mPrincipal;
nsCOMPtr<nsIContentPermissionRequester> mRequester;
};
NS_IMPL_ISUPPORTS(FlyWebPublishServerPermissionCheck,
nsIContentPermissionRequest,
nsIRunnable)
class FlyWebMDNSService final
: public nsIDNSServiceDiscoveryListener
, public nsIDNSServiceResolveListener
@ -955,15 +841,6 @@ FlyWebService::Init()
return ErrorResult(NS_OK);
}
static already_AddRefed<FlyWebPublishPromise>
MakeRejectionPromise(const char* name)
{
MozPromiseHolder<FlyWebPublishPromise> holder;
RefPtr<FlyWebPublishPromise> promise = holder.Ensure(name);
holder.Reject(NS_ERROR_FAILURE, name);
return promise.forget();
}
already_AddRefed<FlyWebPublishPromise>
FlyWebService::PublishServer(const nsAString& aName,
const FlyWebPublishOptions& aOptions,
@ -976,7 +853,10 @@ FlyWebService::PublishServer(const nsAString& aName,
if (existingServer) {
LOG_I("PublishServer: Trying to publish server with already-existing name %s.",
NS_ConvertUTF16toUTF8(aName).get());
return MakeRejectionPromise(__func__);
MozPromiseHolder<FlyWebPublishPromise> holder;
RefPtr<FlyWebPublishPromise> promise = holder.Ensure(__func__);
holder.Reject(NS_ERROR_FAILURE, __func__);
return promise.forget();
}
RefPtr<FlyWebPublishedServer> server;
@ -984,49 +864,6 @@ FlyWebService::PublishServer(const nsAString& aName,
server = new FlyWebPublishedServerChild(aWindow, aName, aOptions);
} else {
server = new FlyWebPublishedServerImpl(aWindow, aName, aOptions);
// Before proceeding, ensure that the FlyWeb system addon exists.
nsresult rv;
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("chrome://flyweb/skin/icon-64.png"));
if (NS_FAILED(rv)) {
return MakeRejectionPromise(__func__);
}
JSAddonId *addonId = MapURIToAddonID(uri);
if (!addonId) {
LOG_E("PublishServer: Failed to find FlyWeb system addon.");
return MakeRejectionPromise(__func__);
}
JSFlatString* flat = JS_ASSERT_STRING_IS_FLAT(JS::StringOfAddonId(addonId));
nsAutoString addonIdString;
AssignJSFlatString(addonIdString, flat);
if (!addonIdString.EqualsLiteral("flyweb@mozilla.org")) {
nsCString addonIdCString = NS_ConvertUTF16toUTF8(addonIdString);
LOG_E("PublishServer: FlyWeb resource found on wrong system addon: %s.", addonIdCString.get());
return MakeRejectionPromise(__func__);
}
}
if (aWindow) {
nsresult rv;
MOZ_ASSERT(NS_IsMainThread());
rv = NS_DispatchToCurrentThread(
MakeAndAddRef<FlyWebPublishServerPermissionCheck>(
NS_ConvertUTF16toUTF8(aName), aWindow->WindowID(), server));
if (NS_WARN_IF(NS_FAILED(rv))) {
LOG_E("PublishServer: Failed to dispatch permission check runnable for %s",
NS_ConvertUTF16toUTF8(aName).get());
return MakeRejectionPromise(__func__);
}
} else {
// If aWindow is null, we're definitely in the e10s parent process.
// In this case, we know that permission has already been granted
// by the user because of content-process prompt.
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
server->PermissionGranted(true);
}
mServers.AppendElement(server);

View File

@ -386,7 +386,7 @@ HTMLButtonElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
// see bug 592124.
// Hold a strong ref while dispatching
RefPtr<HTMLFormElement> form(mForm);
presShell->HandleDOMEventWithTarget(mForm, &event, &status);
presShell->HandleDOMEventWithTarget(form, &event, &status);
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
}
}

View File

@ -3344,7 +3344,7 @@ HTMLInputElement::MaybeSubmitForm(nsPresContext* aPresContext)
RefPtr<mozilla::dom::HTMLFormElement> form = mForm;
InternalFormEvent event(true, eFormSubmit);
nsEventStatus status = nsEventStatus_eIgnore;
shell->HandleDOMEventWithTarget(mForm, &event, &status);
shell->HandleDOMEventWithTarget(form, &event, &status);
}
return NS_OK;
@ -4603,7 +4603,7 @@ HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
mForm->SubmissionCanProceed(this))) {
// Hold a strong ref while dispatching
RefPtr<mozilla::dom::HTMLFormElement> form(mForm);
presShell->HandleDOMEventWithTarget(mForm, &event, &status);
presShell->HandleDOMEventWithTarget(form, &event, &status);
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
}
}

View File

@ -299,7 +299,7 @@ public:
}
RefPtr<HTMLMediaElement> deathGrip = mElement;
mElement->UpdateInitialMediaSize(aSize);
deathGrip->UpdateInitialMediaSize(aSize);
}
void NotifyRealtimeTrackData(MediaStreamGraph* aGraph,
@ -3952,16 +3952,16 @@ public:
mPendingNotifyOutput = false;
}
if (mElement && mHaveCurrentData) {
RefPtr<HTMLMediaElement> deathGrip = mElement;
mElement->FireTimeUpdate(true);
RefPtr<HTMLMediaElement> kungFuDeathGrip = mElement;
kungFuDeathGrip->FireTimeUpdate(true);
}
}
void DoNotifyHaveCurrentData()
{
mHaveCurrentData = true;
if (mElement) {
RefPtr<HTMLMediaElement> deathGrip = mElement;
mElement->FirstFrameLoaded();
RefPtr<HTMLMediaElement> kungFuDeathGrip = mElement;
kungFuDeathGrip->FirstFrameLoaded();
}
NotifyWatchers();
DoNotifyOutput();

View File

@ -139,6 +139,10 @@ HTMLScriptElement::SetText(const nsAString& aValue, ErrorResult& rv)
NS_IMPL_STRING_ATTR(HTMLScriptElement, Charset, charset)
NS_IMPL_BOOL_ATTR(HTMLScriptElement, Defer, defer)
// If this ever gets changed to return "" if the attr value is "" (see
// https://github.com/whatwg/html/issues/1739 for why it might not get changed),
// it may be worth it to use GetSrc instead of GetAttr and manual
// NewURIWithDocumentCharset in FreezeUriAsyncDefer.
NS_IMPL_URI_ATTR(HTMLScriptElement, Src, src)
NS_IMPL_STRING_ATTR(HTMLScriptElement, Type, type)
NS_IMPL_STRING_ATTR(HTMLScriptElement, HtmlFor, _for)
@ -270,11 +274,17 @@ HTMLScriptElement::FreezeUriAsyncDefer()
}
// variation of this code in nsSVGScriptElement - check if changes
// need to be transfered when modifying
if (HasAttr(kNameSpaceID_None, nsGkAtoms::src)) {
nsAutoString src;
GetSrc(src);
NS_NewURI(getter_AddRefs(mUri), src);
// need to be transfered when modifying. Note that we don't use GetSrc here
// because it will return the base URL when the attr value is "".
nsAutoString src;
if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
// Empty src should be treated as invalid URL.
if (!src.IsEmpty()) {
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(mUri),
src, OwnerDoc(), baseURI);
}
// At this point mUri will be null for invalid URLs.
mExternal = true;

View File

@ -361,7 +361,7 @@ ImageDocument::ShrinkToFit()
// Keep image content alive while changing the attributes.
nsCOMPtr<Element> imageContent = mImageContent;
nsCOMPtr<nsIDOMHTMLImageElement> image = do_QueryInterface(mImageContent);
nsCOMPtr<nsIDOMHTMLImageElement> image = do_QueryInterface(imageContent);
image->SetWidth(std::max(1, NSToCoordFloor(GetRatio() * mImageWidth)));
image->SetHeight(std::max(1, NSToCoordFloor(GetRatio() * mImageHeight)));

View File

@ -2658,8 +2658,10 @@ nsHTMLDocument::EditingStateChanged()
if (existingEditor) {
// We might already have an editor if it was set up for mail, let's see
// if this is actually the case.
#ifdef DEBUG
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(existingEditor);
MOZ_ASSERT(htmlEditor, "If we have an editor, it must be an HTML editor");
#endif
uint32_t flags = 0;
existingEditor->GetFlags(&flags);
if (flags & nsIPlaintextEditor::eEditorMailMask) {

View File

@ -2106,7 +2106,7 @@ nsTextEditorState::SetValue(const nsAString& aValue, uint32_t aFlags)
!StringBeginsWith(newValue, currentValue)) {
// Replace the whole text.
currentLength = 0;
mSelCon->SelectAll();
kungFuDeathGrip->SelectAll();
} else {
// Collapse selection to the end so that we can append data.
mBoundFrame->SelectAllOrCollapseToEndOfText(false);

View File

@ -1500,10 +1500,10 @@ BackgroundFactoryRequestChild::RecvBlocked(const uint64_t& aCurrentVersion)
IDB_LOG_MARK("IndexedDB %s: Child Request[%llu]: Firing \"blocked\" event",
"IndexedDB %s: C R[%llu]: \"blocked\"",
IDB_LOG_ID_STRING(),
mRequest->LoggingSerialNumber());
kungFuDeathGrip->LoggingSerialNumber());
bool dummy;
if (NS_FAILED(mRequest->DispatchEvent(blockedEvent, &dummy))) {
if (NS_FAILED(kungFuDeathGrip->DispatchEvent(blockedEvent, &dummy))) {
NS_WARNING("Failed to dispatch event!");
}
@ -1793,7 +1793,7 @@ BackgroundDatabaseChild::RecvVersionChange(const uint64_t& aOldVersion,
RefPtr<IDBDatabase> kungFuDeathGrip = mDatabase;
// Handle bfcache'd windows.
if (nsPIDOMWindowInner* owner = mDatabase->GetOwner()) {
if (nsPIDOMWindowInner* owner = kungFuDeathGrip->GetOwner()) {
// The database must be closed if the window is already frozen.
bool shouldAbortAndClose = owner->IsFrozen();
@ -1809,8 +1809,8 @@ BackgroundDatabaseChild::RecvVersionChange(const uint64_t& aOldVersion,
if (shouldAbortAndClose) {
// Invalidate() doesn't close the database in the parent, so we have
// to call Close() and AbortTransactions() manually.
mDatabase->AbortTransactions(/* aShouldWarn */ false);
mDatabase->Close();
kungFuDeathGrip->AbortTransactions(/* aShouldWarn */ false);
kungFuDeathGrip->Close();
return true;
}
}
@ -1823,13 +1823,13 @@ BackgroundDatabaseChild::RecvVersionChange(const uint64_t& aOldVersion,
switch (aNewVersion.type()) {
case NullableVersion::Tnull_t:
versionChangeEvent =
IDBVersionChangeEvent::Create(mDatabase, type, aOldVersion);
IDBVersionChangeEvent::Create(kungFuDeathGrip, type, aOldVersion);
MOZ_ASSERT(versionChangeEvent);
break;
case NullableVersion::Tuint64_t:
versionChangeEvent =
IDBVersionChangeEvent::Create(mDatabase,
IDBVersionChangeEvent::Create(kungFuDeathGrip,
type,
aOldVersion,
aNewVersion.get_uint64_t());
@ -1845,11 +1845,11 @@ BackgroundDatabaseChild::RecvVersionChange(const uint64_t& aOldVersion,
IDB_LOG_ID_STRING());
bool dummy;
if (NS_FAILED(mDatabase->DispatchEvent(versionChangeEvent, &dummy))) {
if (NS_FAILED(kungFuDeathGrip->DispatchEvent(versionChangeEvent, &dummy))) {
NS_WARNING("Failed to dispatch event!");
}
if (!mDatabase->IsClosed()) {
if (!kungFuDeathGrip->IsClosed()) {
SendBlocked();
}

View File

@ -23949,8 +23949,7 @@ CreateIndexOp::InsertDataFromObjectStoreInternal(
MOZ_ASSERT(!IndexedDatabaseManager::InLowDiskSpaceMode());
MOZ_ASSERT(mMaybeUniqueIndexTable);
nsCOMPtr<mozIStorageConnection> storageConnection =
aConnection->GetStorageConnection();
DebugOnly<void*> storageConnection = aConnection->GetStorageConnection();
MOZ_ASSERT(storageConnection);
DatabaseConnection::CachedStatement stmt;

View File

@ -1665,7 +1665,7 @@ private:
mClosing = true;
nsresult rv = mIOTarget->Dispatch(this, NS_DISPATCH_NORMAL);
nsresult rv = kungFuDeathGrip->Dispatch(this, NS_DISPATCH_NORMAL);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;

View File

@ -5003,7 +5003,6 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
return true;
}
nsCOMPtr<mozIDOMWindowProxy> window;
TabParent::AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
nsCOMPtr<nsPIWindowWatcher> pwwatch =

View File

@ -216,7 +216,7 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel,
nsCOMPtr<nsIScriptGlobalObject> innerGlobal = do_QueryInterface(innerWin);
nsCOMPtr<nsIDOMWindow> domWindow(do_QueryInterface(global, &rv));
mozilla::DebugOnly<nsCOMPtr<nsIDOMWindow>> domWindow(do_QueryInterface(global, &rv));
if (NS_FAILED(rv)) {
return NS_ERROR_FAILURE;
}

View File

@ -881,6 +881,7 @@ GeckoMediaPluginServiceParent::AddPluginDirectory(const nsAString& aDirectory)
{
MOZ_ASSERT(NS_IsMainThread());
RefPtr<GenericPromise> p = AsyncAddPluginDirectory(aDirectory);
Unused << p;
return NS_OK;
}

View File

@ -50,6 +50,7 @@ skip-if = (toolkit == 'gonk') || (toolkit == 'android') || debug #bug 906752
[test_audioBufferSourceNodePassThrough.html]
[test_audioBufferSourceNodeRate.html]
[test_AudioContext.html]
[test_AudioContext_disabled.html]
[test_audioContextSuspendResumeClose.html]
skip-if = buildapp == 'mulet'
tags=capturestream

View File

@ -0,0 +1,56 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test whether we can disable the AudioContext interface</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="webaudio.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
const webaudio_interfaces = [
"AudioContext",
"OfflineAudioContext",
"AudioContext",
"OfflineAudioCompletionEvent",
"AudioNode",
"AudioDestinationNode",
"AudioParam",
"GainNode",
"DelayNode",
"AudioBuffer",
"AudioBufferSourceNode",
"MediaElementAudioSourceNode",
"ScriptProcessorNode",
"AudioProcessingEvent",
"PannerNode",
"AudioListener",
"StereoPannerNode",
"ConvolverNode",
"AnalyserNode",
"ChannelSplitterNode",
"ChannelMergerNode",
"DynamicsCompressorNode",
"BiquadFilterNode",
"IIRFilterNode",
"WaveShaperNode",
"OscillatorNode",
"PeriodicWave",
"MediaStreamAudioSourceNode",
"MediaStreamAudioDestinationNode"
];
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
SpecialPowers.pushPrefEnv({"set": [["dom.webaudio.enabled", false]]}, function() {
webaudio_interfaces.forEach((e) => ok(!window[e], e + " must be disabled when the Web Audio API is disabled"));
SimpleTest.finish();
});
});
</script>
</pre>
</body>
</html>

View File

@ -133,7 +133,7 @@ MessagePortParent::ActorDestroy(ActorDestroyReason aWhy)
// When the last parent is deleted, this service is freed but this cannot
// be done when the hashtables are written by CloseAll.
RefPtr<MessagePortService> kungFuDeathGrip = mService;
mService->ParentDestroy(this);
kungFuDeathGrip->ParentDestroy(this);
}
}

View File

@ -51,7 +51,6 @@ DIRS += [
'contacts',
'crypto',
'phonenumberutils',
'alarm',
'devicestorage',
'encoding',
'events',

View File

@ -281,9 +281,9 @@ static nsCOMPtr<nsIEventTarget> GetSTSThread()
static void CheckSTSThread()
{
nsCOMPtr<nsIEventTarget> sts_thread = GetSTSThread();
DebugOnly<nsCOMPtr<nsIEventTarget>> sts_thread = GetSTSThread();
ASSERT_ON_THREAD(sts_thread);
ASSERT_ON_THREAD(sts_thread.value);
}

View File

@ -2528,7 +2528,7 @@ NotificationWorkerHolder::Notify(Status aStatus)
// Dispatched to main thread, blocks on closing the Notification.
RefPtr<CloseNotificationRunnable> r =
new CloseNotificationRunnable(mNotification);
new CloseNotificationRunnable(kungFuDeathGrip);
ErrorResult rv;
r->Dispatch(rv);
// XXXbz I'm told throwing and returning false from here is pointless (and
@ -2540,7 +2540,7 @@ NotificationWorkerHolder::Notify(Status aStatus)
// ownership (since CloseNotificationRunnable asked the observer to drop the
// reference to the notification).
if (r->HadObserver()) {
mNotification->ReleaseObject();
kungFuDeathGrip->ReleaseObject();
}
// From this point we cannot touch properties of this feature because

View File

@ -4,8 +4,6 @@ support-files =
file_shim.html
file_empty.html
[test_alarms.html]
skip-if = true
[test_browser.html]
skip-if = true
[test_embed-apps.html]

View File

@ -1,35 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=815105
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 815105 </title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=815105">Mozilla Bug 815105 </a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript;version=1.8" src="file_framework.js"></script>
<script type="application/javascript;version=1.8">
var gData = [
{
perm: ["alarms"],
// AlarmsManager is not enabled on Android yet
// exception on accessing AlarmsManager
// See bug 863557
skip: ["Android"],
obj: "mozAlarms",
webidl: "AlarmsManager",
settings: [["dom.mozAlarms.enabled", true]],
},
]
</script>
</pre>
</body>
</html>

View File

@ -318,10 +318,10 @@ nsNPAPIPluginInstance::GetDOMWindow()
if (!mOwner)
return nullptr;
RefPtr<nsPluginInstanceOwner> deathGrip(mOwner);
RefPtr<nsPluginInstanceOwner> kungFuDeathGrip(mOwner);
nsCOMPtr<nsIDocument> doc;
mOwner->GetDocument(getter_AddRefs(doc));
kungFuDeathGrip->GetDocument(getter_AddRefs(doc));
if (!doc)
return nullptr;

View File

@ -424,9 +424,9 @@ nsSMILAnimationController::DoSample(bool aSkipUnchangedContainers)
return;
}
nsCOMPtr<nsIDocument> kungFuDeathGrip(mDocument); // keeps 'this' alive too
nsCOMPtr<nsIDocument> document(mDocument); // keeps 'this' alive too
if (isStyleFlushNeeded) {
mDocument->FlushPendingNotifications(Flush_Style);
document->FlushPendingNotifications(Flush_Style);
}
// WARNING:

View File

@ -37,7 +37,7 @@
navigator.appVersion.indexOf("Android") == -1) {
testObject();
} else {
ok(true, "mozAlarms on Firefox OS only.");
ok(true, "MozSpeakerManager on Firefox OS only.");
SimpleTest.finish();
}
}

View File

@ -154,8 +154,12 @@ SVGScriptElement::FreezeUriAsyncDefer()
mStringAttributes[XLINK_HREF].GetAnimValue(src, this);
}
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
NS_NewURI(getter_AddRefs(mUri), src, nullptr, baseURI);
// Empty src should be treated as invalid URL.
if (!src.IsEmpty()) {
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
NS_NewURI(getter_AddRefs(mUri), src, nullptr, baseURI);
}
// At this point mUri will be null for invalid URLs.
mExternal = true;
}

View File

@ -1,19 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* https://wiki.mozilla.org/WebAPI/AlarmAPI
*/
[NavigatorProperty="mozAlarms",
JSImplementation="@mozilla.org/alarmsManager;1",
Pref="dom.mozAlarms.enabled",
ChromeOnly]
interface AlarmsManager {
DOMRequest getAll();
[UnsafeInPrerendering]
DOMRequest add(any date, DOMString respectTimezone, optional any data);
[UnsafeInPrerendering]
void remove(unsigned long id);
};

View File

@ -10,6 +10,7 @@
* liability, trademark and document use rules apply.
*/
[Pref="dom.webaudio.enabled"]
interface AnalyserNode : AudioNode {
// Real-time frequency-domain data

View File

@ -10,6 +10,7 @@
* liability, trademark and document use rules apply.
*/
[Pref="dom.webaudio.enabled"]
interface AudioBuffer {
readonly attribute float sampleRate;

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