mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Merge m-c to autoland, a=merge
This commit is contained in:
commit
ac33516b3c
@ -124,7 +124,6 @@ XULTreeAccessible::Value(nsString& aValue)
|
||||
return;
|
||||
|
||||
int32_t currentIndex;
|
||||
nsCOMPtr<nsIDOMElement> selectItem;
|
||||
selection->GetCurrentIndex(¤tIndex);
|
||||
if (currentIndex >= 0) {
|
||||
nsCOMPtr<nsITreeColumn> keyCol;
|
||||
|
@ -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);
|
||||
|
@ -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');
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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="▶" onclick="onSearchSubmit(event)"
|
||||
title="&contentSearchSubmit.tooltip;"/>
|
||||
</div>
|
||||
|
||||
<div id="snippetContainer">
|
||||
|
@ -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,
|
||||
|
@ -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="▶"
|
||||
title="&contentSearchSubmit.tooltip;"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
63
browser/themes/shared/ctrlTab.inc.css
Normal file
63
browser/themes/shared/ctrlTab.inc.css
Normal 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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
107
build/clang-plugin/tests/TestKungFuDeathGrip.cpp
Normal file
107
build/clang-plugin/tests/TestKungFuDeathGrip.cpp
Normal 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);
|
@ -15,6 +15,7 @@ SOURCES += [
|
||||
'TestGlobalClass.cpp',
|
||||
'TestHeapClass.cpp',
|
||||
'TestInheritTypeAnnotationsFromTemplateArgs.cpp',
|
||||
'TestKungFuDeathGrip.cpp',
|
||||
'TestMultipleAnnotations.cpp',
|
||||
'TestMustOverride.cpp',
|
||||
'TestMustUse.cpp',
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
@ -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
|
@ -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
|
@ -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();
|
@ -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])
|
@ -1,2 +0,0 @@
|
||||
component {fea1e884-9b05-11e1-9b64-87a7016c3860} AlarmsManager.js
|
||||
contract @mozilla.org/alarmsManager;1 {fea1e884-9b05-11e1-9b64-87a7016c3860}
|
@ -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']
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
@ -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]
|
@ -1,2 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head></head><body><span id="text">Nothing to see here</span><iframe name="subframe"></iframe></body></html>
|
@ -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]
|
@ -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");
|
||||
});
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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();
|
||||
});
|
||||
});
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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
|
@ -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;
|
||||
|
@ -207,6 +207,7 @@ void
|
||||
NodeInfo::DeleteCycleCollectable()
|
||||
{
|
||||
RefPtr<nsNodeInfoManager> kungFuDeathGrip = mOwnerManager;
|
||||
mozilla::Unused << kungFuDeathGrip; // Just keeping value alive for longer than this
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsNetCID.h"
|
||||
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
USING_BLUETOOTH_NAMESPACE
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "nsIUUIDGenerator.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -57,8 +57,6 @@ public:
|
||||
aUiUrl = mUiUrl;
|
||||
}
|
||||
|
||||
virtual void PermissionGranted(bool aGranted) = 0;
|
||||
|
||||
virtual void OnFetchResponse(InternalRequest* aRequest,
|
||||
InternalResponse* aResponse) = 0;
|
||||
already_AddRefed<WebSocket>
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)));
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -5003,7 +5003,6 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<mozIDOMWindowProxy> window;
|
||||
TabParent::AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
|
||||
|
||||
nsCOMPtr<nsPIWindowWatcher> pwwatch =
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -881,6 +881,7 @@ GeckoMediaPluginServiceParent::AddPluginDirectory(const nsAString& aDirectory)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
RefPtr<GenericPromise> p = AsyncAddPluginDirectory(aDirectory);
|
||||
Unused << p;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
56
dom/media/webaudio/test/test_AudioContext_disabled.html
Normal file
56
dom/media/webaudio/test/test_AudioContext_disabled.html
Normal 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>
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,6 @@ DIRS += [
|
||||
'contacts',
|
||||
'crypto',
|
||||
'phonenumberutils',
|
||||
'alarm',
|
||||
'devicestorage',
|
||||
'encoding',
|
||||
'events',
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
@ -10,6 +10,7 @@
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[Pref="dom.webaudio.enabled"]
|
||||
interface AnalyserNode : AudioNode {
|
||||
|
||||
// Real-time frequency-domain data
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user