diff --git a/frontend/device/generic/powerd.lua b/frontend/device/generic/powerd.lua index fc9476c0e..881b5f702 100644 --- a/frontend/device/generic/powerd.lua +++ b/frontend/device/generic/powerd.lua @@ -47,10 +47,13 @@ function BasePowerD:read_str_file(file) end end -function BasePowerD:setIntensity(intensity) +function BasePowerD:normalizeIntensity(intensity) intensity = intensity < self.fl_min and self.fl_min or intensity - intensity = intensity > self.fl_max and self.fl_max or intensity - self.flIntensity = intensity + return intensity > self.fl_max and self.fl_max or intensity +end + +function BasePowerD:setIntensity(intensity) + self.flIntensity = self:normalizeIntensity(intensity) self:setIntensityHW() end diff --git a/frontend/device/kobo/nickel_conf.lua b/frontend/device/kobo/nickel_conf.lua index 976045273..9248f994d 100644 --- a/frontend/device/kobo/nickel_conf.lua +++ b/frontend/device/kobo/nickel_conf.lua @@ -5,10 +5,15 @@ local NickelConf = {} NickelConf.frontLightLevel = {} +NickelConf.frontLightState = {} local kobo_conf_path = '/mnt/onboard/.kobo/Kobo/Kobo eReader.conf' -local re_BrightnessValue = "[0-9]+" -local re_FrontLightLevel = "^FrontLightLevel%s*=%s*(" .. re_BrightnessValue .. ")%s*$" +local front_light_level_str = "FrontLightLevel" +local front_light_state_str = "FrontLightState" +-- Nickel will set FrontLightLevel to 0 - 100 +local re_FrontLightLevel = "^" .. front_light_level_str .. "%s*=%s*([0-9]+)%s*$" +-- Nickel will set FrontLightState to true (light on) or false (light off) +local re_FrontLightState = "^" .. front_light_state_str .. "%s*=%s*(.+)%s*$" local re_PowerOptionsSection = "^%[PowerOptions%]%s*" local re_AnySection = "^%[.*%]%s*" @@ -17,24 +22,20 @@ function NickelConf._set_kobo_conf_path(new_path) kobo_conf_path = new_path end -function NickelConf.frontLightLevel.get() - - local new_intensity +function NickelConf._read_kobo_conf(re_Match) + local value local correct_section = false local kobo_conf = io.open(kobo_conf_path, "r") if kobo_conf then for line in kobo_conf:lines() do - if string.match(line, re_AnySection) then + if string.match(line, re_PowerOptionsSection) then + correct_section = true + elseif string.match(line, re_AnySection) then correct_section = false - if string.match(line, re_PowerOptionsSection) then - correct_section = true - end - end - if correct_section then - new_intensity = string.match(line, re_FrontLightLevel) - if new_intensity then - new_intensity = tonumber(new_intensity) + elseif correct_section then + value = string.match(line, re_Match) + if value then break end end @@ -42,75 +43,108 @@ function NickelConf.frontLightLevel.get() kobo_conf:close() end - if not new_intensity then - local Device = require("device") - local powerd = Device:getPowerDevice() - local fallback_FrontLightLevel = powerd.flIntensity or 1 + return value +end + +function NickelConf.frontLightLevel.get() + local new_intensity = NickelConf._read_kobo_conf(re_FrontLightLevel) + if new_intensity then + new_intensity = tonumber(new_intensity) + end + -- In NickelConfSpec, require("device") won't return KoboDevice + local powerd = require("device/kobo/powerd") + if new_intensity then + return powerd:normalizeIntensity(new_intensity) + else + local fallback_FrontLightLevel = powerd.flIntensity or 1 assert(NickelConf.frontLightLevel.set(fallback_FrontLightLevel)) return fallback_FrontLightLevel end - - return new_intensity end -function NickelConf.frontLightLevel.set(new_intensity) - assert(new_intensity >= 0 and new_intensity <= 100, - "Wrong brightness value given!") +function NickelConf.frontLightState.get() + local new_state = NickelConf._read_kobo_conf(re_FrontLightState) + if new_state then + new_state = (new_state == "true") or false + end - local kobo_conf - local old_intensity - local remaining_file = "" + if new_state == nil then + assert(NickelConf.frontLightState.set(false)) + return false + end + + return new_state +end + +function NickelConf._write_kobo_conf(re_Match, key, value) + local kobo_conf = io.open(kobo_conf_path, "r") local lines = {} - local current_position + local found = false + local remaining local correct_section = false - local modified_brightness = false - - kobo_conf = io.open(kobo_conf_path, "r") + local new_value_line = key .. "=" .. tostring(value) if kobo_conf then + local pos for line in kobo_conf:lines() do if string.match(line, re_AnySection) then if correct_section then -- found a new section after having found the correct one, -- therefore the key was missing: let the code below add it - kobo_conf:seek("set", current_position) + kobo_conf:seek("set", pos) break - end - if string.match(line, re_PowerOptionsSection) then + elseif string.match(line, re_PowerOptionsSection) then correct_section = true end end - old_intensity = string.match(line, re_FrontLightLevel) - if correct_section and old_intensity then - lines[#lines + 1] = string.gsub(line, re_BrightnessValue, new_intensity, 1) - modified_brightness = true + local old_value = string.match(line, re_Match) + if correct_section and old_value then + lines[#lines + 1] = new_value_line + found = true break else lines[#lines + 1] = line end - current_position = kobo_conf:seek() + pos = kobo_conf:seek() end + + remaining = kobo_conf:read("*a") + kobo_conf:close() end - if not modified_brightness then + if not found then if not correct_section then - lines[#lines + 1] = '[PowerOptions]' + lines[#lines + 1] = "[PowerOptions]" end - lines[#lines + 1] = 'FrontLightLevel=' .. new_intensity - end - - if kobo_conf then - remaining_file = kobo_conf:read("*a") - kobo_conf:close() + lines[#lines + 1] = new_value_line end local kobo_conf_w = assert(io.open(kobo_conf_path, "w")) for i, line in ipairs(lines) do kobo_conf_w:write(line, "\n") end - kobo_conf_w:write(remaining_file) + if remaining then + kobo_conf_w:write(remaining) + end kobo_conf_w:close() + return true end +function NickelConf.frontLightLevel.set(new_intensity) + assert(new_intensity >= 0 and new_intensity <= 100, + "Wrong brightness value given!") + return NickelConf._write_kobo_conf(re_FrontLightLevel, + front_light_level_str, + new_intensity) +end + +function NickelConf.frontLightState.set(new_state) + assert(type(new_state) == "boolean", + "Wrong front light state value type (expect boolean)!") + return NickelConf._write_kobo_conf(re_FrontLightState, + front_light_state_str, + new_state) +end + return NickelConf diff --git a/frontend/device/kobo/powerd.lua b/frontend/device/kobo/powerd.lua index 8128ca0df..83929e2a1 100644 --- a/frontend/device/kobo/powerd.lua +++ b/frontend/device/kobo/powerd.lua @@ -1,14 +1,20 @@ local BasePowerD = require("device/generic/powerd") local NickelConf = require("device/kobo/nickel_conf") +local batt_state_folder = + "/sys/devices/platform/pmic_battery.1/power_supply/mc13892_bat/" + local KoboPowerD = BasePowerD:new{ - fl_min = 0, fl_max = 100, + -- Do not actively set front light to 0, it may confuse users -- pressing + -- hardware button won't take any effect. + fl_min = 1, fl_max = 100, flIntensity = 20, restore_settings = true, fl = nil, - batt_capacity_file = "/sys/devices/platform/pmic_battery.1/power_supply/mc13892_bat/capacity", - is_charging_file = "/sys/devices/platform/pmic_battery.1/power_supply/mc13892_bat/status", + flState = false, + batt_capacity_file = batt_state_folder .. "capacity", + is_charging_file = batt_state_folder .. "status", battCapacity = nil, is_charging = nil, } @@ -23,7 +29,15 @@ end function KoboPowerD:toggleFrontlight() if self.fl ~= nil then - self.fl:toggle() + if self.flState then + self.fl:setBrightness(0) + else + self.fl:setBrightness(self.flIntensity) + end + self.flState = not self.flState + if KOBO_SYNC_BRIGHTNESS_WITH_NICKEL then + NickelConf.frontLightState.set(self.flState) + end end end diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index 1ba8d8e49..7576d5c87 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -12,7 +12,8 @@ local MILLION = 1000000 -- there is only one instance of this local UIManager = { -- trigger a full refresh when counter reaches FULL_REFRESH_COUNT - FULL_REFRESH_COUNT = G_reader_settings:readSetting("full_refresh_count") or DRCOUNTMAX, + FULL_REFRESH_COUNT = + G_reader_settings:readSetting("full_refresh_count") or DRCOUNTMAX, refresh_count = 0, event_handlers = nil, @@ -63,17 +64,24 @@ function UIManager:init() local kobo_light_on_start = tonumber(KOBO_LIGHT_ON_START) if kobo_light_on_start then local new_intensity - if kobo_light_on_start >= 0 then + local new_state + if kobo_light_on_start > 0 then new_intensity = math.min(kobo_light_on_start, 100) + new_state = true + elseif kobo_light_on_start == 0 then + new_state = false elseif kobo_light_on_start == -2 then local NickelConf = require("device/kobo/nickel_conf") - new_intensity = NickelConf.frontLightLevel:get() + new_intensity = NickelConf.frontLightLevel.get() + new_state = NickelConf.frontLightState:get() end if new_intensity then -- Since this kobo-specific, we save here and let the code pick -- it up later from the reader settings. - G_reader_settings:saveSetting("frontlight_intensity", new_intensity) + G_reader_settings:saveSetting( + "frontlight_intensity", new_intensity) end + G_reader_settings:saveSetting("frontlight_state", new_state) end elseif Device:isKindle() then self.event_handlers["IntoSS"] = function() diff --git a/reader.lua b/reader.lua index 9dc62a1e2..c014e02b6 100755 --- a/reader.lua +++ b/reader.lua @@ -6,8 +6,12 @@ local DataStorage = require("datastorage") pcall(dofile, DataStorage:getDataDir() .. "/defaults.persistent.lua") -- set search path for 'require()' -package.path = "common/?.lua;rocks/share/lua/5.1/?.lua;frontend/?.lua;" .. package.path -package.cpath = "common/?.so;common/?.dll;/usr/lib/lua/?.so;rocks/lib/lua/5.1/?.so;" .. package.cpath +package.path = + "common/?.lua;rocks/share/lua/5.1/?.lua;frontend/?.lua;" .. + package.path +package.cpath = + "common/?.so;common/?.dll;/usr/lib/lua/?.so;rocks/lib/lua/5.1/?.so;" .. + package.cpath -- set search path for 'ffi.load()' local ffi = require("ffi") @@ -117,8 +121,12 @@ if Device:isKobo() then local powerd = Device:getPowerDevice() if powerd and powerd.restore_settings then local intensity = G_reader_settings:readSetting("frontlight_intensity") - intensity = intensity or powerd.flIntensity - powerd:setIntensity(intensity) + powerd.flIntensity = intensity or powerd.flIntensity + local state = G_reader_settings:readSetting("frontlight_state") + if state then + -- Default state is off + powerd:toggleFrontlight() + end end if Device:getCodeName() == "trilogy" then require("utils/kobo_touch_probe") @@ -132,8 +140,8 @@ if ARGV[argidx] and ARGV[argidx] ~= "" then elseif open_last and last_file then file = last_file end - -- if file is given in command line argument or open last document is set true - -- the given file or the last file is opened in the reader + -- if file is given in command line argument or open last document is set + -- true, the given file or the last file is opened in the reader if file then local ReaderUI = require("apps/reader/readerui") ReaderUI:showReader(file) @@ -141,7 +149,8 @@ if ARGV[argidx] and ARGV[argidx] ~= "" then -- the filemanger will show the files in that path else local FileManager = require("apps/filemanager/filemanager") - local home_dir = G_reader_settings:readSetting("home_dir") or ARGV[argidx] + local home_dir = + G_reader_settings:readSetting("home_dir") or ARGV[argidx] FileManager:showFiles(home_dir) end UIManager:run() @@ -154,7 +163,8 @@ else end local function exitReader() - local ReaderActivityIndicator = require("apps/reader/modules/readeractivityindicator") + local ReaderActivityIndicator = + require("apps/reader/modules/readeractivityindicator") G_reader_settings:close() diff --git a/spec/unit/nickel_conf_spec.lua b/spec/unit/nickel_conf_spec.lua index d77340c1f..44beba96b 100644 --- a/spec/unit/nickel_conf_spec.lua +++ b/spec/unit/nickel_conf_spec.lua @@ -12,6 +12,7 @@ describe("Nickel configuation module", function() foo=bar [PowerOptions] FrontLightLevel=55 +FrontLightState=true [YetAnotherThing] bar=baz ]]) @@ -19,6 +20,46 @@ bar=baz NickelConf._set_kobo_conf_path(fn) assert.Equals(NickelConf.frontLightLevel.get(), 55) + assert.Equals(NickelConf.frontLightState.get(), true) + + os.remove(fn) + end) + + it("should also read value", function() + local fn = os.tmpname() + local fd = io.open(fn, "w") + fd:write([[ +[OtherThing] +foo=bar +[PowerOptions] +FrontLightLevel=30 +FrontLightState=false +[YetAnotherThing] +bar=baz +]]) + fd:close() + + NickelConf._set_kobo_conf_path(fn) + assert.Equals(NickelConf.frontLightLevel.get(), 30) + assert.Equals(NickelConf.frontLightState.get(), false) + + os.remove(fn) + end) + + it("should have default value", function() + local fn = os.tmpname() + local fd = io.open(fn, "w") + fd:write([[ +[OtherThing] +foo=bar +[YetAnotherThing] +bar=baz +]]) + fd:close() + + NickelConf._set_kobo_conf_path(fn) + assert.Equals(NickelConf.frontLightLevel.get(), 20) + assert.Equals(NickelConf.frontLightState.get(), false) os.remove(fn) end) @@ -34,6 +75,7 @@ FrontLightLevel=6 NickelConf._set_kobo_conf_path(fn) NickelConf.frontLightLevel.set(100) + NickelConf.frontLightState.set(true) fd = io.open(fn, "r") assert.Equals(fd:read("*a"), [[ @@ -41,6 +83,7 @@ FrontLightLevel=6 FrontLightLevel=6 [PowerOptions] FrontLightLevel=100 +FrontLightState=true ]]) fd:close() os.remove(fn) @@ -50,11 +93,13 @@ FrontLightLevel=100 fd:close() NickelConf.frontLightLevel.set(20) + NickelConf.frontLightState.set(false) fd = io.open(fn, "r") assert.Equals(fd:read("*a"), [[ [PowerOptions] FrontLightLevel=20 +FrontLightState=false ]]) fd:close() os.remove(fn) @@ -68,6 +113,7 @@ FrontLightLevel=20 foo=bar [PowerOptions] FrontLightLevel=6 +FrontLightState=false [YetAnotherThing] bar=baz ]]) @@ -75,6 +121,7 @@ bar=baz NickelConf._set_kobo_conf_path(fn) NickelConf.frontLightLevel.set(100) + NickelConf.frontLightState.set(true) fd = io.open(fn, "r") assert.Equals(fd:read("*a"), [[ @@ -82,6 +129,7 @@ bar=baz foo=bar [PowerOptions] FrontLightLevel=100 +FrontLightState=true [YetAnotherThing] bar=baz ]]) @@ -102,12 +150,14 @@ bar=baz NickelConf._set_kobo_conf_path(fn) NickelConf.frontLightLevel.set(1) + NickelConf.frontLightState.set(true) fd = io.open(fn, "r") assert.Equals(fd:read("*a"), [[ [PowerOptions] foo=bar FrontLightLevel=1 +FrontLightState=true [OtherThing] bar=baz ]]) @@ -122,11 +172,13 @@ bar=baz NickelConf._set_kobo_conf_path(fn) NickelConf.frontLightLevel.set(15) + NickelConf.frontLightState.set(false) fd = io.open(fn, "r") assert.Equals([[ [PowerOptions] FrontLightLevel=15 +FrontLightState=false ]], fd:read("*a")) fd:close()