richtr / NoSleep.js

Prevent display sleep and enable wake lock in any Android or iOS web browser.
MIT License
2.19k stars 379 forks source link

Make noSleep.enable() idempotent for native WakeLock #118

Open wobedi opened 3 years ago

wobedi commented 3 years ago

Expected Behavior / Situation

When I call noSleep.enable() multiple times and then call noSleep.disable() I would expect all existing WakeLocks to be disabled/released.

Actual Behavior / Situation

I have a use case where noSleep.enable() might be called multiple times instead of just once. Reasons:

Now, as far as I understand the code NoSleep.js will always try to use the native (Chrome) WakeLock if available. Judging by the behavior of my app and looking at the code I believe that noSleep.enable() is currently not idempotent for the native WakeLock.

In my use case, this meant that when I call noSleep.enable() multiple times then NoSleep would (presumably) create multiple WakeLockSentinel objects. The problem is that noSleep.disable() just releases the latest WakeLockSentinel and not the older ones.

This means that when I call noSleep.enable() multiple times I will not be able to use noSleep.disable() to actually release (all) the WakeLock(s). This means that the screen will stay wakelocked, even if I don't want it to.

Modification Proposal

Either maintain a reference to all native wakelocks or (probably better) release the older ones before creating the new one or (probably even better) not create a new one if there is already an existing one.