2023-05-18 21:13:43 +00:00
|
|
|
local Event = require("ui/event")
|
2022-03-14 18:56:18 +00:00
|
|
|
local Math = require("optmath")
|
2023-05-18 21:13:43 +00:00
|
|
|
local UIManager
|
2016-12-29 08:10:38 +00:00
|
|
|
local logger = require("logger")
|
2022-05-05 19:00:22 +00:00
|
|
|
local time = require("ui/time")
|
2014-01-04 13:38:07 +00:00
|
|
|
local BasePowerD = {
|
2017-03-24 06:36:15 +00:00
|
|
|
fl_min = 0, -- min frontlight intensity
|
|
|
|
fl_max = 10, -- max frontlight intensity
|
|
|
|
fl_intensity = nil, -- frontlight intensity
|
2022-03-14 18:56:18 +00:00
|
|
|
fl_warmth_min = 0, -- min warmth level
|
|
|
|
fl_warmth_max = 100, -- max warmth level
|
|
|
|
fl_warmth = nil, -- warmth level
|
2022-01-15 22:36:46 +00:00
|
|
|
batt_capacity = 0, -- battery capacity
|
|
|
|
aux_batt_capacity = 0, -- auxiliary battery capacity
|
2017-03-24 06:36:15 +00:00
|
|
|
device = nil, -- device object
|
2014-07-07 02:50:16 +00:00
|
|
|
|
2022-05-05 19:00:22 +00:00
|
|
|
last_capacity_pull_time = time.s(-61), -- timestamp of last pull
|
|
|
|
last_aux_capacity_pull_time = time.s(-61), -- timestamp of last pull
|
2017-06-14 17:32:16 +00:00
|
|
|
|
|
|
|
is_fl_on = false, -- whether the frontlight is on
|
2014-01-04 13:38:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function BasePowerD:new(o)
|
2016-02-16 07:10:07 +00:00
|
|
|
o = o or {}
|
2014-03-13 13:52:43 +00:00
|
|
|
setmetatable(o, self)
|
|
|
|
self.__index = self
|
2017-06-14 17:32:16 +00:00
|
|
|
assert(o.fl_min < o.fl_max)
|
2014-03-13 13:52:43 +00:00
|
|
|
if o.init then o:init() end
|
2019-04-08 21:05:08 +00:00
|
|
|
if o.device and o.device:hasFrontlight() then
|
2017-06-14 17:32:16 +00:00
|
|
|
o.fl_intensity = o:frontlightIntensityHW()
|
|
|
|
o:_decideFrontlightState()
|
|
|
|
end
|
2022-03-14 18:56:18 +00:00
|
|
|
--- @note: Post-init, as the min/max values may be computed at runtime on some platforms
|
|
|
|
assert(o.fl_warmth_min < o.fl_warmth_max)
|
|
|
|
-- For historical reasons, the *public* PowerD warmth API always expects warmth to be in the [0...100] range...
|
|
|
|
self.warmth_scale = 100 / o.fl_warmth_max
|
|
|
|
--- @note: Some platforms cannot actually read fl/warmth level from the HW,
|
|
|
|
-- in which case the implementation should just return self.fl_warmth (c.f., kobo).
|
|
|
|
if o.device and o.device:hasNaturalLight() then
|
|
|
|
o.fl_warmth = o:frontlightWarmthHW()
|
|
|
|
end
|
2014-03-13 13:52:43 +00:00
|
|
|
return o
|
2014-01-04 13:38:07 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function BasePowerD:init() end
|
Kindle: Fix a smattering of frontlight bugs
* afterResume had *two* different implementations, so the historical one
that handled frontlight fixups no longer ran
(regression since #10426)
* isFrontlightOn was completely broken, for a couple of reasons:
* There was no is isFrontlightOnHW implementation, so when it ran, it
mostly always thought the frontlight was on, because
self.fl_intensity doesn't change on toggle off.
* _decideFrontlightState was never called on Kindle,
so isFrontlightOnHW was never really called, making isFrontlightOn
completely useless. Call it in setIntensityHW's coda, as it ought to
be. And properly document that.
Generic *was* calling _decideFrontlightState is setIntensity, but
*before* actually setting the frontlight, which makes no goddamn sense,
so get rid of that, too.
* Also fix frontlight toggle notifications (regression since #10305)
TL;DR: The PowerD API being a mess strikes again.
2023-11-25 05:30:37 +00:00
|
|
|
--- @note: This should *always* call self:_decideFrontlightState() in its coda (unless you have a custom isFrontlightOn implementation)!
|
|
|
|
function BasePowerD:setIntensityHW(intensity)
|
|
|
|
self:_decideFrontlightState()
|
|
|
|
end
|
2022-03-14 18:56:18 +00:00
|
|
|
--- @note: Unlike the "public" setWarmth, this one takes a value in the *native* scale!
|
|
|
|
function BasePowerD:setWarmthHW(warmth) end
|
2017-03-24 06:36:15 +00:00
|
|
|
function BasePowerD:getCapacityHW() return 0 end
|
2022-01-15 22:36:46 +00:00
|
|
|
function BasePowerD:getAuxCapacityHW() return 0 end
|
|
|
|
function BasePowerD:isAuxBatteryConnectedHW() return false end
|
2021-06-29 12:07:29 +00:00
|
|
|
function BasePowerD:getDismissBatteryStatus() return self.battery_warning end
|
|
|
|
function BasePowerD:setDismissBatteryStatus(status) self.battery_warning = status end
|
A host of low power states related tweaks (#9036)
* Disable all non power management related input during suspend. (This prevents wonky touch events from being tripped when closing a sleep cover on an already-in-suspend device, among other things).
* Kobo: Use our WakeupMgr instance, not the class.
* WakupMgr: split `removeTask` in two:
* `removeTask`, which *only* takes a queue index as input, and only removes a single task. Greatly simplifies the function (i.e., it's just a `table.remove`).
* `removeTasks`, which takes an epoch or a cb ref, and removes *every* task that matches.
* Both of these will also *always* re-schedule the next task (if any) on exit, since we can have multiple WakeupMgr tasks queued, but we can only have a single RTC wake alarm set ;).
* `wakeupAction` now takes a `proximity` argument, which it passes on to its `validateWakeupAlarmByProximity` call, allowing call sites to avoir having to duplicate that call themselves when they want to use a custom proximity window.
* `wakeupAction` now re-schedules the next task (if any) on exit.
* Simplify `Kobo:checkUnexpectedWakeup`, by removing the duplicate `WakerupMgr:validateWakeupAlarmByProximity` call, now that we can pass a proximity window to `WakeuoMgr:wakeupAction`.
* The various network activity timeouts are now halved when autostandby is enabled.
* Autostandby: get rid of the dummy deadline_guard task, as it's no longer necessary since #9009.
* UIManager: The previous change allows us to simplify `getNextTaskTimes` into a simpler `getNextTaskTime` variant, getting rid of a table & a loop.
* ReaderFooter & ReaderHeader: Make sure we only perform a single refresh when exiting standby.
* Kobo: Rewrite sysfs writes to use ANSI C via FFI instead of stdio via Lua, as it obscured some common error cases (e.g., EBUSY on /sys/power/state).
* Kobo: Simplify `suspend`, now that we have sane error handling in sysfs writes.
* Kobo.powerd: Change `isCharging` & `isAuxCharging` behavior to match the behavior of the NTX ioctl (i.e., Charging == Plugged-in). This has the added benefit of making the AutoSuspend checks behave sensibly in the "fully-charged but still plugged in" scenario (because being plugged in is enough to break PM on `!canPowerSaveWhileCharging` devices).
* AutoSuspend: Disable our `AllowStandby` handler when auto standby is disabled, so as to not interfere with other modules using `UIManager:allowStandby` (fix #9038).
* PowerD: Allow platforms to implement `isCharged`, indicating that the battery is full while still plugged in to a power source (battery icon becomes a power plug icon).
* Kobo.powerd: Implement `isCharged`, and kill charging LEDs once battery is full.
* Kindle.powerd: Implement `isCharged` on post-Wario devices. (`isCharging` is still true in that state, as it ought to).
2022-05-01 21:41:08 +00:00
|
|
|
--- @note: Should ideally return true as long as the device is plugged in, even once the battery is full...
|
2017-03-24 06:36:15 +00:00
|
|
|
function BasePowerD:isChargingHW() return false end
|
A host of low power states related tweaks (#9036)
* Disable all non power management related input during suspend. (This prevents wonky touch events from being tripped when closing a sleep cover on an already-in-suspend device, among other things).
* Kobo: Use our WakeupMgr instance, not the class.
* WakupMgr: split `removeTask` in two:
* `removeTask`, which *only* takes a queue index as input, and only removes a single task. Greatly simplifies the function (i.e., it's just a `table.remove`).
* `removeTasks`, which takes an epoch or a cb ref, and removes *every* task that matches.
* Both of these will also *always* re-schedule the next task (if any) on exit, since we can have multiple WakeupMgr tasks queued, but we can only have a single RTC wake alarm set ;).
* `wakeupAction` now takes a `proximity` argument, which it passes on to its `validateWakeupAlarmByProximity` call, allowing call sites to avoir having to duplicate that call themselves when they want to use a custom proximity window.
* `wakeupAction` now re-schedules the next task (if any) on exit.
* Simplify `Kobo:checkUnexpectedWakeup`, by removing the duplicate `WakerupMgr:validateWakeupAlarmByProximity` call, now that we can pass a proximity window to `WakeuoMgr:wakeupAction`.
* The various network activity timeouts are now halved when autostandby is enabled.
* Autostandby: get rid of the dummy deadline_guard task, as it's no longer necessary since #9009.
* UIManager: The previous change allows us to simplify `getNextTaskTimes` into a simpler `getNextTaskTime` variant, getting rid of a table & a loop.
* ReaderFooter & ReaderHeader: Make sure we only perform a single refresh when exiting standby.
* Kobo: Rewrite sysfs writes to use ANSI C via FFI instead of stdio via Lua, as it obscured some common error cases (e.g., EBUSY on /sys/power/state).
* Kobo: Simplify `suspend`, now that we have sane error handling in sysfs writes.
* Kobo.powerd: Change `isCharging` & `isAuxCharging` behavior to match the behavior of the NTX ioctl (i.e., Charging == Plugged-in). This has the added benefit of making the AutoSuspend checks behave sensibly in the "fully-charged but still plugged in" scenario (because being plugged in is enough to break PM on `!canPowerSaveWhileCharging` devices).
* AutoSuspend: Disable our `AllowStandby` handler when auto standby is disabled, so as to not interfere with other modules using `UIManager:allowStandby` (fix #9038).
* PowerD: Allow platforms to implement `isCharged`, indicating that the battery is full while still plugged in to a power source (battery icon becomes a power plug icon).
* Kobo.powerd: Implement `isCharged`, and kill charging LEDs once battery is full.
* Kindle.powerd: Implement `isCharged` on post-Wario devices. (`isCharging` is still true in that state, as it ought to).
2022-05-01 21:41:08 +00:00
|
|
|
--- @note: ...at which point this should start returning true (i.e., plugged in & fully charged).
|
|
|
|
function BasePowerD:isChargedHW() return false end
|
2022-01-15 22:36:46 +00:00
|
|
|
function BasePowerD:isAuxChargingHW() return false end
|
A host of low power states related tweaks (#9036)
* Disable all non power management related input during suspend. (This prevents wonky touch events from being tripped when closing a sleep cover on an already-in-suspend device, among other things).
* Kobo: Use our WakeupMgr instance, not the class.
* WakupMgr: split `removeTask` in two:
* `removeTask`, which *only* takes a queue index as input, and only removes a single task. Greatly simplifies the function (i.e., it's just a `table.remove`).
* `removeTasks`, which takes an epoch or a cb ref, and removes *every* task that matches.
* Both of these will also *always* re-schedule the next task (if any) on exit, since we can have multiple WakeupMgr tasks queued, but we can only have a single RTC wake alarm set ;).
* `wakeupAction` now takes a `proximity` argument, which it passes on to its `validateWakeupAlarmByProximity` call, allowing call sites to avoir having to duplicate that call themselves when they want to use a custom proximity window.
* `wakeupAction` now re-schedules the next task (if any) on exit.
* Simplify `Kobo:checkUnexpectedWakeup`, by removing the duplicate `WakerupMgr:validateWakeupAlarmByProximity` call, now that we can pass a proximity window to `WakeuoMgr:wakeupAction`.
* The various network activity timeouts are now halved when autostandby is enabled.
* Autostandby: get rid of the dummy deadline_guard task, as it's no longer necessary since #9009.
* UIManager: The previous change allows us to simplify `getNextTaskTimes` into a simpler `getNextTaskTime` variant, getting rid of a table & a loop.
* ReaderFooter & ReaderHeader: Make sure we only perform a single refresh when exiting standby.
* Kobo: Rewrite sysfs writes to use ANSI C via FFI instead of stdio via Lua, as it obscured some common error cases (e.g., EBUSY on /sys/power/state).
* Kobo: Simplify `suspend`, now that we have sane error handling in sysfs writes.
* Kobo.powerd: Change `isCharging` & `isAuxCharging` behavior to match the behavior of the NTX ioctl (i.e., Charging == Plugged-in). This has the added benefit of making the AutoSuspend checks behave sensibly in the "fully-charged but still plugged in" scenario (because being plugged in is enough to break PM on `!canPowerSaveWhileCharging` devices).
* AutoSuspend: Disable our `AllowStandby` handler when auto standby is disabled, so as to not interfere with other modules using `UIManager:allowStandby` (fix #9038).
* PowerD: Allow platforms to implement `isCharged`, indicating that the battery is full while still plugged in to a power source (battery icon becomes a power plug icon).
* Kobo.powerd: Implement `isCharged`, and kill charging LEDs once battery is full.
* Kindle.powerd: Implement `isCharged` on post-Wario devices. (`isCharging` is still true in that state, as it ought to).
2022-05-01 21:41:08 +00:00
|
|
|
function BasePowerD:isAuxChargedHW() return false end
|
2017-06-14 17:32:16 +00:00
|
|
|
function BasePowerD:frontlightIntensityHW() return 0 end
|
2017-06-22 02:10:44 +00:00
|
|
|
function BasePowerD:isFrontlightOnHW() return self.fl_intensity > self.fl_min end
|
2023-06-25 09:25:33 +00:00
|
|
|
--- @note: done_callback is used to display Notifications,
|
|
|
|
--- some implementations *may* need to handle it themselves because of timing constraints,
|
|
|
|
--- in which case they should return *true* here, so that the public API knows not to consume the callback early.
|
|
|
|
function BasePowerD:turnOffFrontlightHW(done_callback)
|
|
|
|
self:setIntensityHW(self.fl_min)
|
|
|
|
|
|
|
|
-- Nothing fancy required, so we leave done_callback handling to the public API
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
function BasePowerD:turnOnFrontlightHW(done_callback)
|
|
|
|
--- @fixme: what if fl_intensity == fl_min (c.f., kindle)?
|
|
|
|
self:setIntensityHW(self.fl_intensity)
|
|
|
|
|
|
|
|
return false
|
|
|
|
end
|
2022-03-14 18:56:18 +00:00
|
|
|
function BasePowerD:frontlightWarmthHW() return 0 end
|
|
|
|
-- Anything that needs to be done before doing a real hardware suspend.
|
|
|
|
-- (Such as turning the front light off).
|
2023-05-18 21:13:43 +00:00
|
|
|
-- Do *not* omit calling Device's _beforeSuspend method! This default implementation passes `false` so as *not* to disable input events during PM.
|
|
|
|
function BasePowerD:beforeSuspend() self.device:_beforeSuspend(false) end
|
2022-03-14 18:56:18 +00:00
|
|
|
-- Anything that needs to be done after doing a real hardware resume.
|
|
|
|
-- (Such as restoring front light state).
|
2023-05-18 21:13:43 +00:00
|
|
|
-- Do *not* omit calling Device's _afterResume method!
|
|
|
|
function BasePowerD:afterResume()
|
|
|
|
-- MONOTONIC doesn't tick during suspend,
|
|
|
|
-- invalidate the last battery capacity pull time so that we get up to date data immediately.
|
|
|
|
self:invalidateCapacityCache()
|
|
|
|
|
|
|
|
self.device:_afterResume(false)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Update our UIManager reference once it's ready
|
|
|
|
function BasePowerD:UIManagerReady(uimgr)
|
|
|
|
-- Our own ref
|
|
|
|
UIManager = uimgr
|
|
|
|
-- Let implementations do the same thing, too
|
|
|
|
self:UIManagerReadyHW(uimgr)
|
|
|
|
end
|
|
|
|
-- Ditto, but for implementations
|
|
|
|
function BasePowerD:UIManagerReadyHW(uimgr) end
|
2014-01-04 13:38:07 +00:00
|
|
|
|
2017-06-14 17:32:16 +00:00
|
|
|
function BasePowerD:isFrontlightOn()
|
|
|
|
return self.is_fl_on
|
|
|
|
end
|
|
|
|
|
|
|
|
function BasePowerD:_decideFrontlightState()
|
2019-04-08 21:05:08 +00:00
|
|
|
assert(self.device:hasFrontlight())
|
2017-06-22 02:10:44 +00:00
|
|
|
self.is_fl_on = self:isFrontlightOnHW()
|
2017-06-14 17:32:16 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function BasePowerD:isFrontlightOff()
|
|
|
|
return not self:isFrontlightOn()
|
|
|
|
end
|
|
|
|
|
|
|
|
function BasePowerD:frontlightIntensity()
|
2019-04-08 21:05:08 +00:00
|
|
|
if not self.device:hasFrontlight() then return 0 end
|
2017-06-14 17:32:16 +00:00
|
|
|
if self:isFrontlightOff() then return 0 end
|
2022-03-14 18:56:18 +00:00
|
|
|
--- @note: We assume that nothing other than us will set the frontlight level,
|
|
|
|
--- so we only actually query the HW during initialization.
|
|
|
|
--- (Also, some platforms do not actually have any way of querying the HW).
|
2017-06-14 17:32:16 +00:00
|
|
|
return self.fl_intensity
|
|
|
|
end
|
|
|
|
|
2023-04-30 21:28:30 +00:00
|
|
|
function BasePowerD:toggleFrontlight(done_callback)
|
2019-04-08 21:05:08 +00:00
|
|
|
if not self.device:hasFrontlight() then return false end
|
2017-06-14 17:32:16 +00:00
|
|
|
if self:isFrontlightOn() then
|
2023-04-30 21:28:30 +00:00
|
|
|
return self:turnOffFrontlight(done_callback)
|
2017-06-14 17:32:16 +00:00
|
|
|
else
|
2023-04-30 21:28:30 +00:00
|
|
|
return self:turnOnFrontlight(done_callback)
|
2017-06-14 17:32:16 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-04-30 21:28:30 +00:00
|
|
|
function BasePowerD:turnOffFrontlight(done_callback)
|
2019-04-08 21:05:08 +00:00
|
|
|
if not self.device:hasFrontlight() then return end
|
2017-06-14 17:32:16 +00:00
|
|
|
if self:isFrontlightOff() then return false end
|
2023-06-25 09:25:33 +00:00
|
|
|
local cb_handled = self:turnOffFrontlightHW(done_callback)
|
2019-04-08 21:05:08 +00:00
|
|
|
self.is_fl_on = false
|
2020-09-21 01:48:06 +00:00
|
|
|
self:stateChanged()
|
2023-06-25 09:25:33 +00:00
|
|
|
if not cb_handled and done_callback then
|
|
|
|
done_callback()
|
|
|
|
end
|
2017-06-14 17:32:16 +00:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2023-04-30 21:28:30 +00:00
|
|
|
function BasePowerD:turnOnFrontlight(done_callback)
|
2019-04-08 21:05:08 +00:00
|
|
|
if not self.device:hasFrontlight() then return end
|
2017-06-14 17:32:16 +00:00
|
|
|
if self:isFrontlightOn() then return false end
|
2020-03-26 03:56:34 +00:00
|
|
|
if self.fl_intensity == self.fl_min then return false end --- @fixme what the hell?
|
2023-06-25 09:25:33 +00:00
|
|
|
local cb_handled = self:turnOnFrontlightHW(done_callback)
|
2019-04-08 21:05:08 +00:00
|
|
|
self.is_fl_on = true
|
2020-09-21 01:48:06 +00:00
|
|
|
self:stateChanged()
|
2023-06-25 09:25:33 +00:00
|
|
|
if not cb_handled and done_callback then
|
|
|
|
done_callback()
|
|
|
|
end
|
2017-06-14 17:32:16 +00:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2022-03-14 18:56:18 +00:00
|
|
|
function BasePowerD:frontlightWarmth()
|
|
|
|
if not self.device:hasNaturalLight() then
|
|
|
|
return 0
|
|
|
|
end
|
|
|
|
--- @note: No live query, much like frontlightIntensity
|
|
|
|
return self.fl_warmth
|
|
|
|
end
|
|
|
|
|
2014-01-04 13:38:07 +00:00
|
|
|
function BasePowerD:read_int_file(file)
|
2021-01-16 03:41:46 +00:00
|
|
|
local fd = io.open(file, "r")
|
2014-07-15 08:45:09 +00:00
|
|
|
if fd then
|
2021-01-16 03:41:46 +00:00
|
|
|
local int = fd:read("*number")
|
2014-07-15 08:45:09 +00:00
|
|
|
fd:close()
|
2021-01-16 03:41:46 +00:00
|
|
|
return int or 0
|
2014-07-15 08:45:09 +00:00
|
|
|
else
|
|
|
|
return 0
|
|
|
|
end
|
2014-01-04 13:38:07 +00:00
|
|
|
end
|
|
|
|
|
2022-01-16 18:08:42 +00:00
|
|
|
function BasePowerD:unchecked_read_int_file(file)
|
|
|
|
local fd = io.open(file, "r")
|
|
|
|
if fd then
|
|
|
|
local int = fd:read("*number")
|
|
|
|
fd:close()
|
|
|
|
return int
|
|
|
|
else
|
Assorted bag'o tweaks & fixes (#9569)
* UIManager: Support more specialized update modes for corner-cases:
* A2, which we'll use for the VirtualKeyboards keys (they'd... inadvertently switched to UI with the highlight refactor).
* NO_MERGE variants of ui & partial (for sunxi). Use `[ui]` in ReaderHighlight's popup, because of a Sage kernel bug that could otherwise make it translucent, sometimes completely so (*sigh*).
* UIManager: Assorted code cleanups & simplifications.
* Logger & dbg: Unify logging style, and code cleanups.
* SDL: Unbreak suspend/resume outside of the emulator (fix #9567).
* NetworkMgr: Cache the network status, and allow it to be queried. (Used by AutoSuspend to avoid repeatedly poking the system when computing the standby schedule delay).
* OneTimeMigration: Don't forget about `NETWORK_PROXY` & `STARDICT_DATA_DIR` when migrating `defaults.persistent.lua` (fix #9573)
* WakeupMgr: Workaround an apparent limitation of the RTC found on i.MX5 Kobo devices, where setting a wakealarm further than UINT16_MAX seconds in the future would apparently overflow and wraparound... (fix #8039, many thanks to @yfede for the extensive deep-dive and for actually accurately pinpointing the issue!).
* Kobo: Handle standby transitions at full CPU clock speeds, in order to limit the latency hit.
* UIManager: Properly quit on reboot & exit. This ensures our exit code is preserved, as we exit on our own terms (instead of being killed by the init system). This is important on platforms where exit codes are semantically meaningful (e.g., Kobo).
* UIManager: Speaking of reboot & exit, make sure the Screensaver shows in all circumstances (e.g., autoshutdown, re: #9542)), and that there aren't any extraneous refreshes triggered. (Additionally, fix a minor regression since #9448 about tracking this very transient state on Kobo & Cervantes).
* Kindle: ID the upcoming Scribe.
* Bump base (https://github.com/koreader/koreader-base/pull/1524)
2022-10-02 01:01:49 +00:00
|
|
|
return nil
|
2022-01-16 18:08:42 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-01-17 15:54:49 +00:00
|
|
|
function BasePowerD:read_str_file(file)
|
2021-01-16 03:41:46 +00:00
|
|
|
local fd = io.open(file, "r")
|
2015-01-17 15:54:49 +00:00
|
|
|
if fd then
|
2021-01-16 03:41:46 +00:00
|
|
|
local str = fd:read("*line")
|
2015-01-17 15:54:49 +00:00
|
|
|
fd:close()
|
|
|
|
return str
|
|
|
|
else
|
|
|
|
return ""
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-02-25 08:54:41 +00:00
|
|
|
function BasePowerD:normalizeIntensity(intensity)
|
2014-03-13 13:52:43 +00:00
|
|
|
intensity = intensity < self.fl_min and self.fl_min or intensity
|
2016-02-25 08:54:41 +00:00
|
|
|
return intensity > self.fl_max and self.fl_max or intensity
|
|
|
|
end
|
|
|
|
|
2022-03-14 18:56:18 +00:00
|
|
|
--- @note: Takes an intensity in the native scale (i.e., [self.fl_min, self.fl_max])
|
2016-02-25 08:54:41 +00:00
|
|
|
function BasePowerD:setIntensity(intensity)
|
2019-04-08 21:05:08 +00:00
|
|
|
if not self.device:hasFrontlight() then return false end
|
2017-06-29 06:23:32 +00:00
|
|
|
if intensity == self:frontlightIntensity() then return false end
|
2016-03-02 06:06:21 +00:00
|
|
|
self.fl_intensity = self:normalizeIntensity(intensity)
|
2016-12-29 08:10:38 +00:00
|
|
|
logger.dbg("set light intensity", self.fl_intensity)
|
2020-09-21 01:48:06 +00:00
|
|
|
self:setIntensityHW(self.fl_intensity)
|
|
|
|
self:stateChanged()
|
2017-06-14 17:32:16 +00:00
|
|
|
return true
|
2014-01-04 13:38:07 +00:00
|
|
|
end
|
|
|
|
|
2022-03-14 18:56:18 +00:00
|
|
|
function BasePowerD:normalizeWarmth(warmth)
|
|
|
|
warmth = warmth < 0 and 0 or warmth
|
|
|
|
return warmth > 100 and 100 or warmth
|
|
|
|
end
|
|
|
|
|
|
|
|
function BasePowerD:toNativeWarmth(ko_warmth)
|
|
|
|
return Math.round(ko_warmth / self.warmth_scale)
|
|
|
|
end
|
|
|
|
|
|
|
|
function BasePowerD:fromNativeWarmth(nat_warmth)
|
|
|
|
return Math.round(nat_warmth * self.warmth_scale)
|
|
|
|
end
|
|
|
|
|
|
|
|
--- @note: Takes a warmth in the *KOReader* scale (i.e., [0, 100], *sic*)
|
2022-07-04 04:36:39 +00:00
|
|
|
function BasePowerD:setWarmth(warmth, force_setting)
|
2022-03-14 18:56:18 +00:00
|
|
|
if not self.device:hasNaturalLight() then return false end
|
2022-07-04 04:36:39 +00:00
|
|
|
if not force_setting and warmth == self:frontlightWarmth() then return false end
|
2022-03-14 18:56:18 +00:00
|
|
|
-- Which means that fl_warmth is *also* in the KOReader scale (unlike fl_intensity)
|
|
|
|
self.fl_warmth = self:normalizeWarmth(warmth)
|
|
|
|
local nat_warmth = self:toNativeWarmth(self.fl_warmth)
|
|
|
|
logger.dbg("set light warmth", self.fl_warmth, "->", nat_warmth)
|
|
|
|
self:setWarmthHW(nat_warmth)
|
|
|
|
self:stateChanged()
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2014-01-04 13:38:07 +00:00
|
|
|
function BasePowerD:getCapacity()
|
2022-01-22 22:44:07 +00:00
|
|
|
-- BasePowerD is loaded before UIManager.
|
|
|
|
-- Nothing *currently* calls this before UIManager is actually loaded, but future-proof this anyway.
|
2022-05-05 19:00:22 +00:00
|
|
|
local now
|
2022-01-24 01:49:30 +00:00
|
|
|
if UIManager then
|
2022-05-05 19:00:22 +00:00
|
|
|
now = UIManager:getElapsedTimeSinceBoot()
|
2022-01-22 22:44:07 +00:00
|
|
|
else
|
2022-04-10 22:20:48 +00:00
|
|
|
-- Add time the device was in standby and suspend
|
2022-05-05 19:00:22 +00:00
|
|
|
now = time.now() + self.device.total_standby_time + self.device.total_suspend_time
|
2022-01-22 22:44:07 +00:00
|
|
|
end
|
2022-01-15 22:36:46 +00:00
|
|
|
|
2022-05-05 19:00:22 +00:00
|
|
|
if now - self.last_capacity_pull_time >= time.s(60) then
|
2022-01-15 22:36:46 +00:00
|
|
|
self.batt_capacity = self:getCapacityHW()
|
2022-05-05 19:00:22 +00:00
|
|
|
self.last_capacity_pull_time = now
|
2014-03-13 13:52:43 +00:00
|
|
|
end
|
2022-01-15 22:36:46 +00:00
|
|
|
return self.batt_capacity
|
2014-01-04 13:38:07 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function BasePowerD:isCharging()
|
2014-03-13 13:52:43 +00:00
|
|
|
return self:isChargingHW()
|
2014-01-04 13:38:07 +00:00
|
|
|
end
|
|
|
|
|
A host of low power states related tweaks (#9036)
* Disable all non power management related input during suspend. (This prevents wonky touch events from being tripped when closing a sleep cover on an already-in-suspend device, among other things).
* Kobo: Use our WakeupMgr instance, not the class.
* WakupMgr: split `removeTask` in two:
* `removeTask`, which *only* takes a queue index as input, and only removes a single task. Greatly simplifies the function (i.e., it's just a `table.remove`).
* `removeTasks`, which takes an epoch or a cb ref, and removes *every* task that matches.
* Both of these will also *always* re-schedule the next task (if any) on exit, since we can have multiple WakeupMgr tasks queued, but we can only have a single RTC wake alarm set ;).
* `wakeupAction` now takes a `proximity` argument, which it passes on to its `validateWakeupAlarmByProximity` call, allowing call sites to avoir having to duplicate that call themselves when they want to use a custom proximity window.
* `wakeupAction` now re-schedules the next task (if any) on exit.
* Simplify `Kobo:checkUnexpectedWakeup`, by removing the duplicate `WakerupMgr:validateWakeupAlarmByProximity` call, now that we can pass a proximity window to `WakeuoMgr:wakeupAction`.
* The various network activity timeouts are now halved when autostandby is enabled.
* Autostandby: get rid of the dummy deadline_guard task, as it's no longer necessary since #9009.
* UIManager: The previous change allows us to simplify `getNextTaskTimes` into a simpler `getNextTaskTime` variant, getting rid of a table & a loop.
* ReaderFooter & ReaderHeader: Make sure we only perform a single refresh when exiting standby.
* Kobo: Rewrite sysfs writes to use ANSI C via FFI instead of stdio via Lua, as it obscured some common error cases (e.g., EBUSY on /sys/power/state).
* Kobo: Simplify `suspend`, now that we have sane error handling in sysfs writes.
* Kobo.powerd: Change `isCharging` & `isAuxCharging` behavior to match the behavior of the NTX ioctl (i.e., Charging == Plugged-in). This has the added benefit of making the AutoSuspend checks behave sensibly in the "fully-charged but still plugged in" scenario (because being plugged in is enough to break PM on `!canPowerSaveWhileCharging` devices).
* AutoSuspend: Disable our `AllowStandby` handler when auto standby is disabled, so as to not interfere with other modules using `UIManager:allowStandby` (fix #9038).
* PowerD: Allow platforms to implement `isCharged`, indicating that the battery is full while still plugged in to a power source (battery icon becomes a power plug icon).
* Kobo.powerd: Implement `isCharged`, and kill charging LEDs once battery is full.
* Kindle.powerd: Implement `isCharged` on post-Wario devices. (`isCharging` is still true in that state, as it ought to).
2022-05-01 21:41:08 +00:00
|
|
|
function BasePowerD:isCharged()
|
|
|
|
return self:isChargedHW()
|
|
|
|
end
|
|
|
|
|
2022-01-15 22:36:46 +00:00
|
|
|
function BasePowerD:getAuxCapacity()
|
2022-05-05 19:00:22 +00:00
|
|
|
local now
|
2022-04-08 10:18:23 +00:00
|
|
|
|
2022-01-24 01:49:30 +00:00
|
|
|
if UIManager then
|
2022-05-05 19:00:22 +00:00
|
|
|
now = UIManager:getElapsedTimeSinceBoot()
|
2022-01-22 22:44:07 +00:00
|
|
|
else
|
2022-04-10 22:20:48 +00:00
|
|
|
-- Add time the device was in standby and suspend
|
2022-05-05 19:00:22 +00:00
|
|
|
now = time.now() + self.device.total_standby_time + self.device.total_suspend_time
|
2022-01-22 22:44:07 +00:00
|
|
|
end
|
2022-01-15 22:36:46 +00:00
|
|
|
|
2022-05-05 19:00:22 +00:00
|
|
|
if now - self.last_aux_capacity_pull_time >= time.s(60) then
|
2022-01-16 18:08:42 +00:00
|
|
|
local aux_batt_capa = self:getAuxCapacityHW()
|
|
|
|
-- If the read failed, don't update our cache, and retry next time.
|
|
|
|
if aux_batt_capa then
|
|
|
|
self.aux_batt_capacity = aux_batt_capa
|
2022-05-05 19:00:22 +00:00
|
|
|
self.last_aux_capacity_pull_time = now
|
2022-01-16 18:08:42 +00:00
|
|
|
end
|
2022-01-15 22:36:46 +00:00
|
|
|
end
|
|
|
|
return self.aux_batt_capacity
|
|
|
|
end
|
|
|
|
|
2022-01-23 17:46:37 +00:00
|
|
|
function BasePowerD:invalidateCapacityCache()
|
2022-05-05 19:00:22 +00:00
|
|
|
self.last_capacity_pull_time = time.s(-61)
|
|
|
|
self.last_aux_capacity_pull_time = self.last_capacity_pull_time
|
2022-01-23 17:46:37 +00:00
|
|
|
end
|
|
|
|
|
2022-01-15 22:36:46 +00:00
|
|
|
function BasePowerD:isAuxCharging()
|
|
|
|
return self:isAuxChargingHW()
|
|
|
|
end
|
|
|
|
|
A host of low power states related tweaks (#9036)
* Disable all non power management related input during suspend. (This prevents wonky touch events from being tripped when closing a sleep cover on an already-in-suspend device, among other things).
* Kobo: Use our WakeupMgr instance, not the class.
* WakupMgr: split `removeTask` in two:
* `removeTask`, which *only* takes a queue index as input, and only removes a single task. Greatly simplifies the function (i.e., it's just a `table.remove`).
* `removeTasks`, which takes an epoch or a cb ref, and removes *every* task that matches.
* Both of these will also *always* re-schedule the next task (if any) on exit, since we can have multiple WakeupMgr tasks queued, but we can only have a single RTC wake alarm set ;).
* `wakeupAction` now takes a `proximity` argument, which it passes on to its `validateWakeupAlarmByProximity` call, allowing call sites to avoir having to duplicate that call themselves when they want to use a custom proximity window.
* `wakeupAction` now re-schedules the next task (if any) on exit.
* Simplify `Kobo:checkUnexpectedWakeup`, by removing the duplicate `WakerupMgr:validateWakeupAlarmByProximity` call, now that we can pass a proximity window to `WakeuoMgr:wakeupAction`.
* The various network activity timeouts are now halved when autostandby is enabled.
* Autostandby: get rid of the dummy deadline_guard task, as it's no longer necessary since #9009.
* UIManager: The previous change allows us to simplify `getNextTaskTimes` into a simpler `getNextTaskTime` variant, getting rid of a table & a loop.
* ReaderFooter & ReaderHeader: Make sure we only perform a single refresh when exiting standby.
* Kobo: Rewrite sysfs writes to use ANSI C via FFI instead of stdio via Lua, as it obscured some common error cases (e.g., EBUSY on /sys/power/state).
* Kobo: Simplify `suspend`, now that we have sane error handling in sysfs writes.
* Kobo.powerd: Change `isCharging` & `isAuxCharging` behavior to match the behavior of the NTX ioctl (i.e., Charging == Plugged-in). This has the added benefit of making the AutoSuspend checks behave sensibly in the "fully-charged but still plugged in" scenario (because being plugged in is enough to break PM on `!canPowerSaveWhileCharging` devices).
* AutoSuspend: Disable our `AllowStandby` handler when auto standby is disabled, so as to not interfere with other modules using `UIManager:allowStandby` (fix #9038).
* PowerD: Allow platforms to implement `isCharged`, indicating that the battery is full while still plugged in to a power source (battery icon becomes a power plug icon).
* Kobo.powerd: Implement `isCharged`, and kill charging LEDs once battery is full.
* Kindle.powerd: Implement `isCharged` on post-Wario devices. (`isCharging` is still true in that state, as it ought to).
2022-05-01 21:41:08 +00:00
|
|
|
function BasePowerD:isAuxCharged()
|
|
|
|
return self:isAuxChargedHW()
|
|
|
|
end
|
|
|
|
|
2022-01-15 22:36:46 +00:00
|
|
|
function BasePowerD:isAuxBatteryConnected()
|
|
|
|
return self:isAuxBatteryConnectedHW()
|
|
|
|
end
|
|
|
|
|
2020-09-21 01:48:06 +00:00
|
|
|
function BasePowerD:stateChanged()
|
2020-09-17 17:49:03 +00:00
|
|
|
-- BasePowerD is loaded before UIManager. So we cannot broadcast events before UIManager has been loaded.
|
2022-01-24 01:49:30 +00:00
|
|
|
if UIManager then
|
2017-06-20 02:00:36 +00:00
|
|
|
UIManager:broadcastEvent(Event:new("FrontlightStateChanged"))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-01-30 22:25:06 +00:00
|
|
|
-- Silly helper to avoid code duplication ;).
|
A host of low power states related tweaks (#9036)
* Disable all non power management related input during suspend. (This prevents wonky touch events from being tripped when closing a sleep cover on an already-in-suspend device, among other things).
* Kobo: Use our WakeupMgr instance, not the class.
* WakupMgr: split `removeTask` in two:
* `removeTask`, which *only* takes a queue index as input, and only removes a single task. Greatly simplifies the function (i.e., it's just a `table.remove`).
* `removeTasks`, which takes an epoch or a cb ref, and removes *every* task that matches.
* Both of these will also *always* re-schedule the next task (if any) on exit, since we can have multiple WakeupMgr tasks queued, but we can only have a single RTC wake alarm set ;).
* `wakeupAction` now takes a `proximity` argument, which it passes on to its `validateWakeupAlarmByProximity` call, allowing call sites to avoir having to duplicate that call themselves when they want to use a custom proximity window.
* `wakeupAction` now re-schedules the next task (if any) on exit.
* Simplify `Kobo:checkUnexpectedWakeup`, by removing the duplicate `WakerupMgr:validateWakeupAlarmByProximity` call, now that we can pass a proximity window to `WakeuoMgr:wakeupAction`.
* The various network activity timeouts are now halved when autostandby is enabled.
* Autostandby: get rid of the dummy deadline_guard task, as it's no longer necessary since #9009.
* UIManager: The previous change allows us to simplify `getNextTaskTimes` into a simpler `getNextTaskTime` variant, getting rid of a table & a loop.
* ReaderFooter & ReaderHeader: Make sure we only perform a single refresh when exiting standby.
* Kobo: Rewrite sysfs writes to use ANSI C via FFI instead of stdio via Lua, as it obscured some common error cases (e.g., EBUSY on /sys/power/state).
* Kobo: Simplify `suspend`, now that we have sane error handling in sysfs writes.
* Kobo.powerd: Change `isCharging` & `isAuxCharging` behavior to match the behavior of the NTX ioctl (i.e., Charging == Plugged-in). This has the added benefit of making the AutoSuspend checks behave sensibly in the "fully-charged but still plugged in" scenario (because being plugged in is enough to break PM on `!canPowerSaveWhileCharging` devices).
* AutoSuspend: Disable our `AllowStandby` handler when auto standby is disabled, so as to not interfere with other modules using `UIManager:allowStandby` (fix #9038).
* PowerD: Allow platforms to implement `isCharged`, indicating that the battery is full while still plugged in to a power source (battery icon becomes a power plug icon).
* Kobo.powerd: Implement `isCharged`, and kill charging LEDs once battery is full.
* Kindle.powerd: Implement `isCharged` on post-Wario devices. (`isCharging` is still true in that state, as it ought to).
2022-05-01 21:41:08 +00:00
|
|
|
function BasePowerD:getBatterySymbol(is_charged, is_charging, capacity)
|
|
|
|
if is_charged then
|
|
|
|
return ""
|
|
|
|
elseif is_charging then
|
2022-01-30 22:25:06 +00:00
|
|
|
return ""
|
|
|
|
else
|
|
|
|
if capacity >= 100 then
|
|
|
|
return ""
|
|
|
|
elseif capacity >= 90 then
|
|
|
|
return ""
|
|
|
|
elseif capacity >= 80 then
|
|
|
|
return ""
|
|
|
|
elseif capacity >= 70 then
|
|
|
|
return ""
|
|
|
|
elseif capacity >= 60 then
|
|
|
|
return ""
|
|
|
|
elseif capacity >= 50 then
|
|
|
|
return ""
|
|
|
|
elseif capacity >= 40 then
|
|
|
|
return ""
|
|
|
|
elseif capacity >= 30 then
|
|
|
|
return ""
|
|
|
|
elseif capacity >= 20 then
|
|
|
|
return ""
|
|
|
|
elseif capacity >= 10 then
|
|
|
|
return ""
|
|
|
|
else
|
|
|
|
return ""
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-01-04 13:38:07 +00:00
|
|
|
return BasePowerD
|