mirror of
https://github.com/koreader/koreader
synced 2024-11-11 19:11:14 +00:00
5146358605
As early as turnOnWifi. Implement it on hasWifiManager platforms, preventing useless connectivity checks to run when they're obviously never going to work because you're out of range of your AP. Also implemented a flag to notify the backend if the connection attempt was interactive or not. Right now, interactive is extremely restricted, it basically means the menu checkmark, or a gesture. The intent being that for stuff like the beforeWifiAction framework, we don't want the backend to spawn extra UI. Specifically, for hasWifiManager platforms, we no longer spawn the AP scan list on failure unless the caller was interactive. TL;DR: beforeWifiAction is now much less obnoxious when you're obviously not able to connect.
290 lines
9.5 KiB
Lua
290 lines
9.5 KiB
Lua
local Generic = require("device/generic/device")
|
|
local logger = require("logger")
|
|
|
|
local function yes() return true end
|
|
local function no() return false end
|
|
|
|
local function getProductId()
|
|
local ntxinfo_pcb = io.popen("/usr/bin/ntxinfo /dev/mmcblk0 | grep pcb | cut -d ':' -f2", "r")
|
|
if not ntxinfo_pcb then return 0 end
|
|
local product_id = ntxinfo_pcb:read("*number") or 0
|
|
ntxinfo_pcb:close()
|
|
return product_id
|
|
end
|
|
|
|
local function isMassStorageSupported()
|
|
-- we rely on 3rd party package for that. It should be installed as part of KOReader prerequisites,
|
|
local safemode_version = io.open("/usr/share/safemode/version", "rb")
|
|
if not safemode_version then return false end
|
|
safemode_version:close()
|
|
return true
|
|
end
|
|
|
|
local Cervantes = Generic:extend{
|
|
model = "Cervantes",
|
|
isCervantes = yes,
|
|
isAlwaysPortrait = yes,
|
|
isTouchDevice = yes,
|
|
touch_legacy = true, -- SingleTouch input events
|
|
touch_switch_xy = true,
|
|
touch_mirrored_x = true,
|
|
hasOTAUpdates = yes,
|
|
hasFastWifiStatusQuery = yes,
|
|
hasKeys = yes,
|
|
hasWifiManager = yes,
|
|
hasWifiRestore = yes,
|
|
canReboot = yes,
|
|
canPowerOff = yes,
|
|
canSuspend = yes,
|
|
supportsScreensaver = yes,
|
|
home_dir = "/mnt/public",
|
|
|
|
-- do we support usb mass storage?
|
|
canToggleMassStorage = function() return isMassStorageSupported() end,
|
|
|
|
-- all devices, except the original Cervantes Touch, have frontlight
|
|
hasFrontlight = yes,
|
|
|
|
-- currently only Cervantes 4 has coloured frontlight
|
|
hasNaturalLight = no,
|
|
hasNaturalLightMixer = no,
|
|
|
|
-- HW inversion is generally safe on Cervantes, except on a few boards/kernels
|
|
canHWInvert = yes,
|
|
}
|
|
-- Cervantes Touch
|
|
local CervantesTouch = Cervantes:extend{
|
|
model = "CervantesTouch",
|
|
display_dpi = 167,
|
|
hasFrontlight = no,
|
|
hasMultitouch = no,
|
|
}
|
|
-- Cervantes TouchLight / Fnac Touch Plus
|
|
local CervantesTouchLight = Cervantes:extend{
|
|
model = "CervantesTouchLight",
|
|
display_dpi = 167,
|
|
hasMultitouch = no,
|
|
}
|
|
-- Cervantes 2013 / Fnac Touch Light
|
|
local Cervantes2013 = Cervantes:extend{
|
|
model = "Cervantes2013",
|
|
display_dpi = 212,
|
|
hasMultitouch = no,
|
|
--- @fixme: Possibly requires canHWInvert = no, as it seems to be based on a similar board as the Kobo Aura...
|
|
}
|
|
-- Cervantes 3 / Fnac Touch Light 2
|
|
local Cervantes3 = Cervantes:extend{
|
|
model = "Cervantes3",
|
|
display_dpi = 300,
|
|
hasMultitouch = no,
|
|
}
|
|
-- Cervantes 4
|
|
local Cervantes4 = Cervantes:extend{
|
|
model = "Cervantes4",
|
|
display_dpi = 300,
|
|
hasNaturalLight = yes,
|
|
frontlight_settings = {
|
|
frontlight_white = "/sys/class/backlight/mxc_msp430_fl.0/brightness",
|
|
frontlight_mixer = "/sys/class/backlight/lm3630a_led/color",
|
|
nl_min = 0,
|
|
nl_max = 10,
|
|
nl_inverted = true,
|
|
},
|
|
}
|
|
|
|
-- input events
|
|
function Cervantes:initEventAdjustHooks()
|
|
if self.touch_switch_xy and self.touch_mirrored_x then
|
|
self.input:registerEventAdjustHook(
|
|
self.input.adjustTouchSwitchAxesAndMirrorX,
|
|
(self.screen:getWidth() - 1)
|
|
)
|
|
end
|
|
|
|
if self.touch_legacy then
|
|
self.input.handleTouchEv = self.input.handleTouchEvLegacy
|
|
end
|
|
end
|
|
|
|
function Cervantes:init()
|
|
self.screen = require("ffi/framebuffer_mxcfb"):new{device = self, debug = logger.dbg, is_always_portrait = self.isAlwaysPortrait()}
|
|
|
|
-- Automagically set this so we never have to remember to do it manually ;p
|
|
if self:hasNaturalLight() and self.frontlight_settings and self.frontlight_settings.frontlight_mixer then
|
|
self.hasNaturalLightMixer = yes
|
|
end
|
|
|
|
self.powerd = require("device/cervantes/powerd"):new{device = self}
|
|
self.input = require("device/input"):new{
|
|
device = self,
|
|
event_map = {
|
|
[61] = "Home",
|
|
[116] = "Power",
|
|
}
|
|
}
|
|
self.input.open("/dev/input/event0") -- Keys
|
|
self.input.open("/dev/input/event1") -- touchscreen
|
|
self.input.open("fake_events") -- usb events
|
|
self:initEventAdjustHooks()
|
|
Generic.init(self)
|
|
end
|
|
|
|
function Cervantes:setDateTime(year, month, day, hour, min, sec)
|
|
if hour == nil or min == nil then return true end
|
|
local command
|
|
if year and month and day then
|
|
command = string.format("date -s '%d-%d-%d %d:%d:%d'", year, month, day, hour, min, sec)
|
|
else
|
|
command = string.format("date -s '%d:%d'",hour, min)
|
|
end
|
|
if os.execute(command) == 0 then
|
|
os.execute('hwclock -u -w')
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
function Cervantes:saveSettings()
|
|
self.powerd:saveSettings()
|
|
end
|
|
|
|
-- wireless
|
|
function Cervantes:initNetworkManager(NetworkMgr)
|
|
function NetworkMgr:turnOffWifi(complete_callback)
|
|
logger.info("Cervantes: disabling Wi-Fi")
|
|
self:releaseIP()
|
|
os.execute("./disable-wifi.sh")
|
|
if complete_callback then
|
|
complete_callback()
|
|
end
|
|
end
|
|
function NetworkMgr:turnOnWifi(complete_callback, interactive)
|
|
logger.info("Cervantes: enabling Wi-Fi")
|
|
os.execute("./enable-wifi.sh")
|
|
return self:reconnectOrShowNetworkMenu(complete_callback, interactive)
|
|
end
|
|
function NetworkMgr:getNetworkInterfaceName()
|
|
return "eth0"
|
|
end
|
|
NetworkMgr:setWirelessBackend("wpa_supplicant", {ctrl_interface = "/var/run/wpa_supplicant/eth0"})
|
|
function NetworkMgr:obtainIP()
|
|
os.execute("./obtain-ip.sh")
|
|
end
|
|
function NetworkMgr:releaseIP()
|
|
os.execute("./release-ip.sh")
|
|
end
|
|
function NetworkMgr:restoreWifiAsync()
|
|
os.execute("./restore-wifi-async.sh")
|
|
end
|
|
NetworkMgr.isWifiOn = NetworkMgr.sysfsWifiOn
|
|
NetworkMgr.isConnected = NetworkMgr.ifHasAnAddress
|
|
end
|
|
|
|
-- power functions: suspend, resume, reboot, poweroff
|
|
function Cervantes:suspend()
|
|
os.execute("./suspend.sh")
|
|
end
|
|
function Cervantes:resume()
|
|
os.execute("./resume.sh")
|
|
end
|
|
function Cervantes:reboot()
|
|
os.execute("sleep 1 && reboot &")
|
|
end
|
|
function Cervantes:powerOff()
|
|
os.execute("sleep 1 && halt &")
|
|
end
|
|
|
|
-- This method is the same as the one in kobo/device.lua except the sleep cover part.
|
|
function Cervantes:setEventHandlers(UIManager)
|
|
-- We do not want auto suspend procedure to waste battery during
|
|
-- suspend. So let's unschedule it when suspending, and restart it after
|
|
-- resume. Done via the plugin's onSuspend/onResume handlers.
|
|
UIManager.event_handlers.Suspend = function()
|
|
self:onPowerEvent("Suspend")
|
|
end
|
|
UIManager.event_handlers.Resume = function()
|
|
self:onPowerEvent("Resume")
|
|
end
|
|
UIManager.event_handlers.PowerPress = function()
|
|
-- Always schedule power off.
|
|
-- Press the power button for 2+ seconds to shutdown directly from suspend.
|
|
UIManager:scheduleIn(2, UIManager.poweroff_action)
|
|
end
|
|
UIManager.event_handlers.PowerRelease = function()
|
|
if not UIManager._entered_poweroff_stage then
|
|
UIManager:unschedule(UIManager.poweroff_action)
|
|
-- resume if we were suspended
|
|
if self.screen_saver_mode then
|
|
if self.screen_saver_lock then
|
|
UIManager.event_handlers.Suspend()
|
|
else
|
|
UIManager.event_handlers.Resume()
|
|
end
|
|
else
|
|
UIManager.event_handlers.Suspend()
|
|
end
|
|
end
|
|
end
|
|
UIManager.event_handlers.Light = function()
|
|
self:getPowerDevice():toggleFrontlight()
|
|
end
|
|
-- USB plug events with a power-only charger
|
|
UIManager.event_handlers.Charging = function()
|
|
self:_beforeCharging()
|
|
-- NOTE: Plug/unplug events will wake the device up, which is why we put it back to sleep.
|
|
if self.screen_saver_mode and not self.screen_saver_lock then
|
|
UIManager.event_handlers.Suspend()
|
|
end
|
|
end
|
|
UIManager.event_handlers.NotCharging = function()
|
|
-- We need to put the device into suspension, other things need to be done before it.
|
|
self:usbPlugOut()
|
|
self:_afterNotCharging()
|
|
if self.screen_saver_mode and not self.screen_saver_lock then
|
|
UIManager.event_handlers.Suspend()
|
|
end
|
|
end
|
|
-- USB plug events with a data-aware host
|
|
UIManager.event_handlers.UsbPlugIn = function()
|
|
self:_beforeCharging()
|
|
-- NOTE: Plug/unplug events will wake the device up, which is why we put it back to sleep.
|
|
if self.screen_saver_mode and not self.screen_saver_lock then
|
|
UIManager.event_handlers.Suspend()
|
|
elseif not self.screen_saver_lock then
|
|
-- Potentially start an USBMS session
|
|
local MassStorage = require("ui/elements/mass_storage")
|
|
MassStorage:start()
|
|
end
|
|
end
|
|
UIManager.event_handlers.UsbPlugOut = function()
|
|
-- We need to put the device into suspension, other things need to be done before it.
|
|
self:usbPlugOut()
|
|
self:_afterNotCharging()
|
|
if self.screen_saver_mode and not self.screen_saver_lock then
|
|
UIManager.event_handlers.Suspend()
|
|
elseif not self.screen_saver_lock then
|
|
-- Potentially dismiss the USBMS ConfirmBox
|
|
local MassStorage = require("ui/elements/mass_storage")
|
|
MassStorage:dismiss()
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------- device probe ------------
|
|
local product_id = getProductId()
|
|
|
|
if product_id == 22 then
|
|
return CervantesTouch
|
|
elseif product_id == 23 then
|
|
return CervantesTouchLight
|
|
elseif product_id == 33 then
|
|
return Cervantes2013
|
|
elseif product_id == 51 then
|
|
return Cervantes3
|
|
elseif product_id == 68 then
|
|
return Cervantes4
|
|
else
|
|
error("unrecognized Cervantes: board id " .. product_id)
|
|
end
|