Bug 1579522 - Allow skipping first update timer interval r=kmag

The UpdateTimerManager has an undocumented behaviour for firing its listeners
very soon after first registration (about 10min into the first session).

Let's document that behaviour, and make it optional.

Differential Revision: https://phabricator.services.mozilla.com/D46292

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Chris H-C 2019-10-09 20:18:55 +00:00
Родитель 0733410a0c
Коммит 0037974a9f
4 изменённых файлов: 59 добавлений и 4 удалений

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

@ -342,8 +342,10 @@ TimerManager.prototype = {
/**
* See nsIUpdateTimerManager.idl
*/
registerTimer: function TM_registerTimer(id, callback, interval) {
LOG(`TimerManager:registerTimer - timerID: ${id} interval: ${interval}`);
registerTimer: function TM_registerTimer(id, callback, interval, skipFirst) {
LOG(
`TimerManager:registerTimer - timerID: ${id} interval: ${interval} skipFirst: ${skipFirst}`
);
if (this._timers === null) {
// Use normal logging since reportError is not available while shutting
// down.
@ -370,6 +372,9 @@ TimerManager.prototype = {
lastUpdateTime = 0;
}
if (lastUpdateTime == 0) {
if (skipFirst) {
lastUpdateTime = now;
}
Services.prefs.setIntPref(prefLastUpdate, lastUpdateTime);
}
this._timers[id] = { callback, interval, lastUpdateTime };

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

@ -19,7 +19,8 @@ interface nsIUpdateTimerManager : nsISupports
* Register an interval with the timer manager. The timer manager
* periodically checks to see if the interval has expired and if it has
* calls the specified callback. This is persistent across application
* restarts and can handle intervals of long durations.
* restarts and can handle intervals of long durations. The callback will be
* called soon after the first registration unless you ask to skip it.
* @param id
* An id that identifies the interval, used for persistence
* @param callback
@ -27,6 +28,8 @@ interface nsIUpdateTimerManager : nsISupports
* expires
* @param interval
* The length of time, in seconds, of the interval
* @param skipFirst
* Whether to skip the initial callback on first registration.
*
* Note: to avoid having to instantiate a component to call registerTimer
* the component can intead register an update-timer category with comma
@ -46,7 +49,8 @@ interface nsIUpdateTimerManager : nsISupports
*/
void registerTimer(in AString id,
in nsITimerCallback callback,
in unsigned long interval);
in unsigned long interval,
[optional] in boolean skipFirst);
/**
* Unregister an existing interval from the timer manager.

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

@ -0,0 +1,45 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
"use strict";
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
XPCOMUtils.defineLazyServiceGetter(
this,
"gUpdateTimerManager",
"@mozilla.org/updates/timer-manager;1",
"nsIUpdateTimerManager"
);
const PREF_APP_UPDATE_LASTUPDATETIME_FMT = "app.update.lastUpdateTime.%ID%";
add_task(async function() {
const testId = "test_timer_id";
const testPref = PREF_APP_UPDATE_LASTUPDATETIME_FMT.replace(/%ID%/, testId);
const testInterval = 100000000; // Just needs to be longer than the test.
Services.prefs.clearUserPref(testPref);
gUpdateTimerManager.registerTimer(
testId,
{},
testInterval,
true /* skipFirst */
);
let prefValue = Services.prefs.getIntPref(testPref, 0);
Assert.notEqual(
prefValue,
0,
"Last update time for test timer must not be 0."
);
let nowSeconds = Date.now() / 1000; // update timer lastUpdate prefs are set in seconds.
Assert.ok(
Math.abs(nowSeconds - prefValue) < 2,
"Last update time for test timer must be now-ish."
);
gUpdateTimerManager.unregisterTimer(testId);
});

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

@ -6,3 +6,4 @@
head =
[consumerNotifications.js]
[test_skipFirst.js]