nsITimer & hibernation

Talk about code development, features, specific bugs, enhancements, patches, and similar things.
Forum rules
Please keep everything here strictly on-topic.
This board is meant for Pale Moon source code development related subjects only like code snippets, patches, specific bugs, git, the repositories, etc.

This is not for tech support! Please do not post tech support questions in the "Development" board!
Please make sure not to use this board for support questions. Please post issues with specific websites, extensions, etc. in the relevant boards for those topics.

Please keep things on-topic as this forum will be used for reference for Pale Moon development. Expect topics that aren't relevant as such to be moved or deleted.
User avatar
moonbat
Knows the dark side
Knows the dark side
Posts: 4159
Joined: 2015-12-09, 15:45
Contact:

nsITimer & hibernation

Unread post by moonbat » 2022-10-06, 00:41

I use an nsITimer in my extension AutoPageColor to figure out whether the current time falls between sunrise and sunset, and then change the prefers_color_scheme setting accordingly.
However, if I hibernate my laptop (Linux Mint 20.3) with PM running, then when it resumes the following day (or night, this is when the extension is supposed to switch between day and night or vice versa) the timer doesn't work even though from the log I can see that the callback function is being called.
I invoke the timer based on whether the extension's automatic setting is enabled in the color preferences dialog like so (shown below as well)

Code: Select all

if(branch.getBoolPref("enabled",false)) {
		AutoPageColor.Common.printlog("Enabling timer.")
		AutoPageColor.Common.timer.init(AutoPageColor.Common.timeObserver,
		AutoPageColor.APC_TIMER_DELAY,AutoPageColor.Common.timer.TYPE_REPEATING_PRECISE_CAN_SKIP);
	}
which uses the callback timeObserver:

Code: Select all

timeObserver : {
    	observe : function(aSubject,aTopic,aData){
    		if(aTopic == 'timer-callback' && Common.prefBranch.getBoolPref("enabled",false) 
    			&& Services.prefs.getIntPref("browser.display.prefers_color_scheme") > 0){
    			let sunrise = new Date(Common.prefBranch.getCharPref("sunrise"));
    			let sunset = new Date(Common.prefBranch.getCharPref("sunset"));
    			let current = new Date();
    			let now = current.getTime();
    			Common.printlog("Inside timer at "+Common.formatDate(current));
    			let title = Common.strBundle.GetStringFromName("notification.title");
    			if(Services.prefs.getIntPref("browser.display.prefers_color_scheme") == 1 && 
    				(now > sunset.getTime() || now < sunrise.getTime())){
    					Services.prefs.setIntPref("browser.display.prefers_color_scheme",2); //dark theme
    					Common.showAlert(true);
    			} else if(Services.prefs.getIntPref("browser.display.prefers_color_scheme") == 2 && 
    			(now > sunrise.getTime() && now < sunset.getTime())){
    				Services.prefs.setIntPref("browser.display.prefers_color_scheme",1); //light theme
    				Common.showAlert(false);
    			}
    		}
    	}
    }
Interestingly, the same problem is seen with the web extension Dark Reader that I use in Brave; this extension combines the features of mine with Swarth to automatically change colors based on time schedule or sunrise/sunset times. For both this and my extension, I end up having to manually set light/dark mode after resuming from hibernation. If I restart PM (or Brave) then the corresponding extensions work as intended and automatically switch to the correct day/night mode.

So I'm wondering if it's a generic OS level quirk with creating repeating timers since it applies to 2 totally different browsers.
"One hosts to look them up, one DNS to find them and in the darkness BIND them."

Image
Linux Mint 21 Xfce x64 on HP i5-5200 laptop, 12 GB RAM.
AutoPageColor|PermissionsPlus|PMPlayer|Pure URL|RecordRewind|TextFX

User avatar
Kris_88
Lunatic
Lunatic
Posts: 360
Joined: 2021-01-26, 11:18

Re: nsITimer & hibernation

Unread post by Kris_88 » 2022-10-06, 17:35

You probably do not update the YY/MM/DD part of the sunrise and sunset prefs when the date changes. So, sunrise and sunset point to the previous day and they are always lower than current datetime. I did not study your sources deeply, so I can make a mistake.

BTW, why are you using TYPE_REPEATING_PRECISE_CAN_SKIP ?
A more relaxed option TYPE_REPEATING_SLACK is quite suitable there.

User avatar
moonbat
Knows the dark side
Knows the dark side
Posts: 4159
Joined: 2015-12-09, 15:45
Contact:

Re: nsITimer & hibernation

Unread post by moonbat » 2022-10-07, 03:55

Kris_88 wrote:
2022-10-06, 17:35
You probably do not update the YY/MM/DD part of the sunrise and sunset prefs when the date changes.
I'm using SunCalc, it takes care of the time calculation reliably. With logging enabled, it correctly displays the calculated times and the current time, so it ought to fire. Restarting the browser fixes it.
Regarding slack vs skip, I figured it needs to exactly switch over at the calculated times. Will try with slack.
"One hosts to look them up, one DNS to find them and in the darkness BIND them."

Image
Linux Mint 21 Xfce x64 on HP i5-5200 laptop, 12 GB RAM.
AutoPageColor|PermissionsPlus|PMPlayer|Pure URL|RecordRewind|TextFX

User avatar
Moonchild
Pale Moon guru
Pale Moon guru
Posts: 32992
Joined: 2011-08-28, 17:27
Location: Tranås, SE
Contact:

Re: nsITimer & hibernation

Unread post by Moonchild » 2022-10-07, 04:08

Hibernation is tricky. If you allow it to skip, then it's possible it won't fire if too much time has passed...
The browser has a ton of timers running at all times, and those tend to all fire together when you resume, which may also interfere, depending on how the timer is set up.
"The best revenge is to not be like the person who wronged you." -- Marcus Aurelius
"Seek wisdom, not knowledge. Knowledge is of the past; wisdom is of the future." -- Native American proverb

User avatar
moonbat
Knows the dark side
Knows the dark side
Posts: 4159
Joined: 2015-12-09, 15:45
Contact:

Re: nsITimer & hibernation

Unread post by moonbat » 2022-10-07, 04:15

So would it be a good idea to reinitialize the timer every few hours?
"One hosts to look them up, one DNS to find them and in the darkness BIND them."

Image
Linux Mint 21 Xfce x64 on HP i5-5200 laptop, 12 GB RAM.
AutoPageColor|PermissionsPlus|PMPlayer|Pure URL|RecordRewind|TextFX

User avatar
Kris_88
Lunatic
Lunatic
Posts: 360
Joined: 2021-01-26, 11:18

Re: nsITimer & hibernation

Unread post by Kris_88 » 2022-10-07, 07:06

I change your logging a bit. And set timer to 10s.
So,

Code: Select all

//    			Common.printlog("Inside timer at "+Common.formatDate(current));
    			Common.printlog("timer: \ncurrent=" + current.toString() +
                         " \nsunrise=" + sunrise.toString() +
                         " \nsunset=" + sunset.toString()
                        );
Look how it works:
[AutoPageColor:] Enabling timer.
[AutoPageColor:] timer:
current=Fri Oct 07 2022 09:47:47 GMT+0300 (FLE Standard Time)
sunrise=Fri Oct 07 2022 09:11:14 GMT+0300 (FLE Standard Time)
sunset=Fri Oct 07 2022 20:26:57 GMT+0300 (FLE Standard Time)
[AutoPageColor:] timer:
current=Fri Oct 07 2022 09:47:57 GMT+0300 (FLE Standard Time)
sunrise=Fri Oct 07 2022 09:11:14 GMT+0300 (FLE Standard Time)
sunset=Fri Oct 07 2022 20:26:57 GMT+0300 (FLE Standard Time)
[AutoPageColor:] timer:
current=Fri Oct 07 2022 09:48:07 GMT+0300 (FLE Standard Time)
sunrise=Fri Oct 07 2022 09:11:14 GMT+0300 (FLE Standard Time)
sunset=Fri Oct 07 2022 20:26:57 GMT+0300 (FLE Standard Time)

At this moment I changed the date on the computer.


[AutoPageColor:] timer:
current=Sat Oct 08 2022 09:48:16 GMT+0300 (FLE Standard Time)
sunrise=Fri Oct 07 2022 09:11:14 GMT+0300 (FLE Standard Time)
sunset=Fri Oct 07 2022 20:26:57 GMT+0300 (FLE Standard Time)
[AutoPageColor:] Switching to dark colors.
[AutoPageColor:] timer:
current=Sat Oct 08 2022 09:48:26 GMT+0300 (FLE Standard Time)
sunrise=Fri Oct 07 2022 09:11:14 GMT+0300 (FLE Standard Time)
sunset=Fri Oct 07 2022 20:26:57 GMT+0300 (FLE Standard Time)
[AutoPageColor:] timer:
current=Sat Oct 08 2022 09:48:36 GMT+0300 (FLE Standard Time)
sunrise=Fri Oct 07 2022 09:11:14 GMT+0300 (FLE Standard Time)
sunset=Fri Oct 07 2022 20:26:57 GMT+0300 (FLE Standard Time)
[AutoPageColor:] timer:
current=Sat Oct 08 2022 09:48:46 GMT+0300 (FLE Standard Time)
sunrise=Fri Oct 07 2022 09:11:14 GMT+0300 (FLE Standard Time)
sunset=Fri Oct 07 2022 20:26:57 GMT+0300 (FLE Standard Time)
Well, everything, as I said: the dates of sunrise and sunset remained in the previous day. And the current date will never fall between them.

User avatar
Moonchild
Pale Moon guru
Pale Moon guru
Posts: 32992
Joined: 2011-08-28, 17:27
Location: Tranås, SE
Contact:

Re: nsITimer & hibernation

Unread post by Moonchild » 2022-10-07, 08:55

Kris_88 wrote:
2022-10-07, 07:06
as I said: the dates of sunrise and sunset remained in the previous day. And the current date will never fall between them.
That isn't a problem, really, because then it will just default to dark.

Code: Select all

now > sunset.getTime() || now < sunrise.getTime()
However, it'd be a problem if you've entirely skipped a period because it also checks if the pref is set on the "dark theme" at the same time.

So you need to adjust that logic a little to account for the situation where you'd wake up the system, and browser.display.prefers_color_scheme is set to 2 AND the time is less than sunrise.getTime() because it'd been asleep. Currently, the system would never get out of that state.

There is also a warning on the nsITimer MDN page that you need to hold a reference to it, or it may potentially not fire. Perhaps that is the problem, i.e. it gets GCed and won't fire anymore?
"The best revenge is to not be like the person who wronged you." -- Marcus Aurelius
"Seek wisdom, not knowledge. Knowledge is of the past; wisdom is of the future." -- Native American proverb

User avatar
Kris_88
Lunatic
Lunatic
Posts: 360
Joined: 2021-01-26, 11:18

Re: nsITimer & hibernation

Unread post by Kris_88 » 2022-10-07, 09:25

Moonchild wrote:
2022-10-07, 08:55
That isn't a problem, really, because then it will just default to dark.

Code: Select all

now > sunset.getTime() || now < sunrise.getTime()
That is a problem, because it will just default to dark forever (until the app restart).
Because sunrise & sunset are updated when restarting only.
The dates 2022/10/08, 2022/10/09, 2022/10/10... , are always greater than any time point within 2022/10/07.
So, now > sunset.getTime() forever.
Moonchild wrote:
2022-10-07, 08:55
Perhaps that is the problem, i.e. it gets GCed and won't fire anymore?
He keep the pointer. The problem is not in the timer.

Code: Select all

Common = {
...
	timer : Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer),
...
}

User avatar
Kris_88
Lunatic
Lunatic
Posts: 360
Joined: 2021-01-26, 11:18

Re: nsITimer & hibernation

Unread post by Kris_88 » 2022-10-07, 09:32

Maybe you think the getTime() returns the time of day? This is not true.
getTime() returns the number of milliseconds since January 1, 1970 00:00:00.

User avatar
Moonchild
Pale Moon guru
Pale Moon guru
Posts: 32992
Joined: 2011-08-28, 17:27
Location: Tranås, SE
Contact:

Re: nsITimer & hibernation

Unread post by Moonchild » 2022-10-07, 09:37

Well, instead of using the stored prefs in the callback, why not just recalculate sunrise and sunset? I didn't really look too much into the rest of the scripting.
"The best revenge is to not be like the person who wronged you." -- Marcus Aurelius
"Seek wisdom, not knowledge. Knowledge is of the past; wisdom is of the future." -- Native American proverb

User avatar
moonbat
Knows the dark side
Knows the dark side
Posts: 4159
Joined: 2015-12-09, 15:45
Contact:

Re: nsITimer & hibernation

Unread post by moonbat » 2022-10-07, 10:17

Thanks for helping with this, I'll give these a try :thumbup:
"One hosts to look them up, one DNS to find them and in the darkness BIND them."

Image
Linux Mint 21 Xfce x64 on HP i5-5200 laptop, 12 GB RAM.
AutoPageColor|PermissionsPlus|PMPlayer|Pure URL|RecordRewind|TextFX

Post Reply