mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Various Wi-Fi QoL improvements (#6424)
* Revamped most actions that require an internet connection to a new/fixed backend that allows forwarding the initial action and running it automatically once connected. (i.e., it'll allow you to set "Action when Wi-Fi is off" to "turn_on", and whatch stuff connect and do what you wanted automatically without having to re-click anywhere instead of showing you a Wi-Fi prompt and then not doing anything without any other feedback). * Speaking of, fixed the "turn_on" beforeWifi action to, well, actually work. It's no longer marked as experimental. * Consistently use "Wi-Fi" everywhere. * On Kobo/Cervantes/Sony, implemented a "Kill Wi-Fi connection when inactive" system that will automatically disconnect from Wi-Fi after sustained *network* inactivity (i.e., you can keep reading, it'll eventually turn off on its own). This should be smart and flexible enough not to murder Wi-Fi while you need it, while still not keeping it uselessly on and murdering your battery. (i.e., enable that + turn Wi-Fi on when off and enjoy never having to bother about Wi-Fi ever again). * Made sending `NetworkConnected` / `NetworkDisconnected` events consistent (they were only being sent... sometimes, which made relying on 'em somewhat problematic). * restoreWifiAsync is now only run when really needed (i.e., we no longer stomp on an existing working connection just for the hell of it). * We no longer attempt to kill a bogus non-existent Wi-Fi connection when going to suspend, we only do it when it's actually needed. * Every method of enabling Wi-Fi will now properly tear down Wi-Fi on failure, instead of leaving it in an undefined state. * Fixed an issue in the fancy crash screen on Kobo/reMarkable that could sometime lead to the log excerpt being missing. * Worked-around a number of sneaky issues related to low-level Wi-Fi/DHCP/DNS handling on Kobo (see the lengthy comments [below](https://github.com/koreader/koreader/pull/6424#issuecomment-663881059) for details). Fix #6421 Incidentally, this should also fix the inconsistencies experienced re: Wi-Fi behavior in Nickel when toggling between KOReader and Nickel (use NM/KFMon, and run a current FW for best results). * For developers, this involves various cleanups around NetworkMgr and NetworkListener. Documentation is in-line, above the concerned functions.
This commit is contained in:
@@ -149,20 +149,17 @@ function CloudStorage:openCloudServer(url)
|
||||
local tbl
|
||||
local NetworkMgr = require("ui/network/manager")
|
||||
if self.type == "dropbox" then
|
||||
if not NetworkMgr:isOnline() then
|
||||
NetworkMgr:promptWifiOn()
|
||||
if NetworkMgr:willRerunWhenOnline(function() self:openCloudServer(url) end) then
|
||||
return
|
||||
end
|
||||
tbl = DropBox:run(url, self.password, self.choose_folder_mode)
|
||||
elseif self.type == "ftp" then
|
||||
if not NetworkMgr:isConnected() then
|
||||
NetworkMgr:promptWifiOn()
|
||||
if NetworkMgr:willRerunWhenConnected(function() self:openCloudServer(url) end) then
|
||||
return
|
||||
end
|
||||
tbl = Ftp:run(self.address, self.username, self.password, url)
|
||||
elseif self.type == "webdav" then
|
||||
if not NetworkMgr:isConnected() then
|
||||
NetworkMgr:promptWifiOn()
|
||||
if NetworkMgr:willRerunWhenConnected(function() self:openCloudServer(url) end) then
|
||||
return
|
||||
end
|
||||
tbl = WebDav:run(self.address, self.username, self.password, url)
|
||||
|
||||
@@ -836,11 +836,10 @@ function ReaderDictionary:showDownload(downloadable_dicts)
|
||||
for dummy, dict in ipairs(downloadable_dicts) do
|
||||
table.insert(kv_pairs, {dict.name, "",
|
||||
callback = function()
|
||||
if not NetworkMgr:isOnline() then
|
||||
NetworkMgr:promptWifiOn()
|
||||
return
|
||||
local connect_callback = function()
|
||||
self:downloadDictionaryPrep(dict)
|
||||
end
|
||||
self:downloadDictionaryPrep(dict)
|
||||
NetworkMgr:runWhenOnline(connect_callback)
|
||||
end})
|
||||
local lang
|
||||
if dict.lang_in == dict.lang_out then
|
||||
|
||||
@@ -57,7 +57,7 @@ local symbol_prefix = {
|
||||
frontlight = C_("FooterLetterPrefix", "L:"),
|
||||
-- @translators This is the footer letter prefix for memory usage.
|
||||
mem_usage = C_("FooterLetterPrefix", "M:"),
|
||||
-- @translators This is the footer letter prefix for wifi status.
|
||||
-- @translators This is the footer letter prefix for Wi-Fi status.
|
||||
wifi_status = C_("FooterLetterPrefix", "W:"),
|
||||
},
|
||||
icons = {
|
||||
@@ -1835,7 +1835,7 @@ function ReaderFooter:applyFooterMode(mode)
|
||||
-- 7 for from statistics chapter time to read
|
||||
-- 8 for front light level
|
||||
-- 9 for memory usage
|
||||
-- 10 for wifi status
|
||||
-- 10 for Wi-Fi status
|
||||
-- 11 for book title
|
||||
-- 12 for current chapter
|
||||
|
||||
|
||||
@@ -384,10 +384,11 @@ function ReaderWikipedia:onLookupWikipedia(word, box, get_fullpage, forced_lang)
|
||||
end
|
||||
|
||||
function ReaderWikipedia:lookupWikipedia(word, box, get_fullpage, forced_lang)
|
||||
if not NetworkMgr:isOnline() then
|
||||
NetworkMgr:promptWifiOn()
|
||||
if NetworkMgr:willRerunWhenOnline(function() self:lookupWikipedia(word, box, get_fullpage, forced_lang) end) then
|
||||
-- Not online yet, nothing more to do here, NetworkMgr will forward the callback and run it once connected!
|
||||
return
|
||||
end
|
||||
|
||||
-- word is the text to query. If get_fullpage is true, it is the
|
||||
-- exact wikipedia page title we want the full page of.
|
||||
self:initLanguages(word)
|
||||
@@ -525,11 +526,10 @@ function ReaderWikipedia:onSaveSettings()
|
||||
end
|
||||
|
||||
function ReaderWikipedia:onShowWikipediaLookup()
|
||||
if NetworkMgr:isOnline() then
|
||||
local connect_callback = function()
|
||||
self:lookupInput()
|
||||
else
|
||||
NetworkMgr:promptWifiOn()
|
||||
end
|
||||
NetworkMgr:runWhenOnline(connect_callback)
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ local function isConnected()
|
||||
-- read carrier state from sysfs (for eth0)
|
||||
local file = io.open("/sys/class/net/eth0/carrier", "rb")
|
||||
|
||||
-- file exists while wifi module is loaded.
|
||||
-- file exists while Wi-Fi module is loaded.
|
||||
if not file then return 0 end
|
||||
|
||||
-- 0 means not connected, 1 connected
|
||||
@@ -224,7 +224,7 @@ end
|
||||
-- wireless
|
||||
function Cervantes:initNetworkManager(NetworkMgr)
|
||||
function NetworkMgr:turnOffWifi(complete_callback)
|
||||
logger.info("Cervantes: disabling WiFi")
|
||||
logger.info("Cervantes: disabling Wi-Fi")
|
||||
self:releaseIP()
|
||||
os.execute("./disable-wifi.sh")
|
||||
if complete_callback then
|
||||
@@ -232,10 +232,13 @@ function Cervantes:initNetworkManager(NetworkMgr)
|
||||
end
|
||||
end
|
||||
function NetworkMgr:turnOnWifi(complete_callback)
|
||||
logger.info("Cervantes: enabling WiFi")
|
||||
logger.info("Cervantes: enabling Wi-Fi")
|
||||
os.execute("./enable-wifi.sh")
|
||||
self:reconnectOrShowNetworkMenu(complete_callback)
|
||||
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")
|
||||
|
||||
@@ -282,12 +282,12 @@ function Device:onPowerEvent(ev)
|
||||
self.screen_saver_mode = true
|
||||
UIManager:scheduleIn(0.1, function()
|
||||
local network_manager = require("ui/network/manager")
|
||||
-- NOTE: wifi_was_on does not necessarily mean that WiFi is *currently* on! It means *we* enabled it.
|
||||
-- NOTE: wifi_was_on does not necessarily mean that Wi-Fi is *currently* on! It means *we* enabled it.
|
||||
-- This is critical on Kobos (c.f., #3936), where it might still be on from KSM or Nickel,
|
||||
-- without us being aware of it (i.e., wifi_was_on still unset or false),
|
||||
-- because suspend will at best fail, and at worst deadlock the system if WiFi is on,
|
||||
-- because suspend will at best fail, and at worst deadlock the system if Wi-Fi is on,
|
||||
-- regardless of who enabled it!
|
||||
if network_manager.wifi_was_on or network_manager:isWifiOn() then
|
||||
if network_manager:isWifiOn() then
|
||||
network_manager:releaseIP()
|
||||
network_manager:turnOffWifi()
|
||||
end
|
||||
|
||||
@@ -12,7 +12,7 @@ local function kindleEnableWifi(toggle)
|
||||
end
|
||||
if lipc_handle then
|
||||
-- Be extremely thorough... c.f., #6019
|
||||
-- NOTE: I *assume* this'll also ensure we prefer WiFi over 3G/4G, which is a plus in my book...
|
||||
-- NOTE: I *assume* this'll also ensure we prefer Wi-Fi over 3G/4G, which is a plus in my book...
|
||||
if toggle == 1 then
|
||||
lipc_handle:set_int_property("com.lab126.cmd", "wirelessEnable", 1)
|
||||
lipc_handle:set_int_property("com.lab126.wifid", "enable", 1)
|
||||
@@ -103,20 +103,19 @@ function Kindle:initNetworkManager(NetworkMgr)
|
||||
function NetworkMgr:turnOnWifi(complete_callback)
|
||||
kindleEnableWifi(1)
|
||||
-- NOTE: As we defer the actual work to lipc,
|
||||
-- we have no guarantee the WiFi state will have changed by the time kindleEnableWifi returns,
|
||||
-- so, delay the callback a bit...
|
||||
-- we have no guarantee the Wi-Fi state will have changed by the time kindleEnableWifi returns,
|
||||
-- so, delay the callback until we at least can ensure isConnect is true.
|
||||
if complete_callback then
|
||||
local UIManager = require("ui/uimanager")
|
||||
UIManager:scheduleIn(1, complete_callback)
|
||||
NetworkMgr:scheduleConnectivityCheck(complete_callback)
|
||||
end
|
||||
end
|
||||
|
||||
function NetworkMgr:turnOffWifi(complete_callback)
|
||||
kindleEnableWifi(0)
|
||||
-- NOTE: Same here...
|
||||
-- NOTE: Same here, except disconnect is simpler, so a dumb delay will do...
|
||||
if complete_callback then
|
||||
local UIManager = require("ui/uimanager")
|
||||
UIManager:scheduleIn(1, complete_callback)
|
||||
UIManager:scheduleIn(2, complete_callback)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -374,7 +373,7 @@ local KindleOasis = Kindle:new{
|
||||
hasGSensor = yes,
|
||||
display_dpi = 300,
|
||||
--[[
|
||||
-- NOTE: Points to event3 on WiFi devices, event4 on 3G devices...
|
||||
-- NOTE: Points to event3 on Wi-Fi devices, event4 on 3G devices...
|
||||
-- 3G devices apparently have an extra SX9500 Proximity/Capacitive controller for mysterious purposes...
|
||||
-- This evidently screws with the ordering, so, use the udev by-path path instead to avoid hackier workarounds.
|
||||
-- cf. #2181
|
||||
@@ -405,7 +404,7 @@ local KindlePaperWhite4 = Kindle:new{
|
||||
display_dpi = 300,
|
||||
-- NOTE: LTE devices once again have a mysterious extra SX9310 proximity sensor...
|
||||
-- Except this time, we can't rely on by-path, because there's no entry for the TS :/.
|
||||
-- Should be event2 on WiFi, event3 on LTE, we'll fix it in init.
|
||||
-- Should be event2 on Wi-Fi, event3 on LTE, we'll fix it in init.
|
||||
touch_dev = "/dev/input/event2",
|
||||
}
|
||||
|
||||
|
||||
@@ -10,11 +10,11 @@ local function yes() return true end
|
||||
local function no() return false end
|
||||
|
||||
local function koboEnableWifi(toggle)
|
||||
if toggle == 1 then
|
||||
logger.info("Kobo WiFi: enabling WiFi")
|
||||
if toggle == true then
|
||||
logger.info("Kobo Wi-Fi: enabling Wi-Fi")
|
||||
os.execute("./enable-wifi.sh")
|
||||
else
|
||||
logger.info("Kobo WiFi: disabling WiFi")
|
||||
logger.info("Kobo Wi-Fi: disabling Wi-Fi")
|
||||
os.execute("./disable-wifi.sh")
|
||||
end
|
||||
end
|
||||
@@ -414,14 +414,15 @@ end
|
||||
|
||||
function Kobo:initNetworkManager(NetworkMgr)
|
||||
function NetworkMgr:turnOffWifi(complete_callback)
|
||||
koboEnableWifi(0)
|
||||
self:releaseIP()
|
||||
koboEnableWifi(false)
|
||||
if complete_callback then
|
||||
complete_callback()
|
||||
end
|
||||
end
|
||||
|
||||
function NetworkMgr:turnOnWifi(complete_callback)
|
||||
koboEnableWifi(1)
|
||||
koboEnableWifi(true)
|
||||
self:showNetworkMenu(complete_callback)
|
||||
end
|
||||
|
||||
@@ -429,6 +430,9 @@ function Kobo:initNetworkManager(NetworkMgr)
|
||||
if not net_if then
|
||||
net_if = "eth0"
|
||||
end
|
||||
function NetworkMgr:getNetworkInterfaceName()
|
||||
return net_if
|
||||
end
|
||||
NetworkMgr:setWirelessBackend(
|
||||
"wpa_supplicant", {ctrl_interface = "/var/run/wpa_supplicant/" .. net_if})
|
||||
|
||||
@@ -444,14 +448,14 @@ function Kobo:initNetworkManager(NetworkMgr)
|
||||
os.execute("./restore-wifi-async.sh")
|
||||
end
|
||||
|
||||
-- NOTE: Cheap-ass way of checking if WiFi seems to be enabled...
|
||||
-- NOTE: Cheap-ass way of checking if Wi-Fi seems to be enabled...
|
||||
-- Since the crux of the issues lies in race-y module unloading, this is perfectly fine for our usage.
|
||||
function NetworkMgr:isWifiOn()
|
||||
local fd = io.open("/proc/modules", "r")
|
||||
if fd then
|
||||
local lsmod = fd:read("*all")
|
||||
fd:close()
|
||||
-- lsmod is usually empty, unless WiFi or USB is enabled
|
||||
-- lsmod is usually empty, unless Wi-Fi or USB is enabled
|
||||
-- We could alternatively check if lfs.attributes("/proc/sys/net/ipv4/conf/" .. os.getenv("INTERFACE"), "mode") == "directory"
|
||||
-- c.f., also what Cervantes does via /sys/class/net/eth0/carrier to check if the interface is up.
|
||||
-- That said, since we only care about whether *modules* are loaded, this does the job nicely.
|
||||
|
||||
@@ -158,6 +158,10 @@ function SonyPRSTUX:initNetworkManager(NetworkMgr)
|
||||
self:showNetworkMenu(complete_callback)
|
||||
end
|
||||
|
||||
function NetworkMgr:getNetworkInterfaceName()
|
||||
return "wlan0"
|
||||
end
|
||||
|
||||
NetworkMgr:setWirelessBackend("wpa_supplicant", {ctrl_interface = "/var/run/wpa_supplicant/wlan0"})
|
||||
|
||||
function NetworkMgr:obtainIP()
|
||||
|
||||
@@ -62,9 +62,11 @@ local order = {
|
||||
network = {
|
||||
"network_wifi",
|
||||
"network_proxy",
|
||||
"network_powersave",
|
||||
"network_restore",
|
||||
"network_info",
|
||||
"network_before_wifi_action",
|
||||
"network_after_wifi_action",
|
||||
"network_dismiss_scan",
|
||||
"----------------------------",
|
||||
"ssh",
|
||||
|
||||
@@ -83,9 +83,11 @@ local order = {
|
||||
network = {
|
||||
"network_wifi",
|
||||
"network_proxy",
|
||||
"network_powersave",
|
||||
"network_restore",
|
||||
"network_info",
|
||||
"network_before_wifi_action",
|
||||
"network_after_wifi_action",
|
||||
"network_dismiss_scan",
|
||||
"----------------------------",
|
||||
"ssh",
|
||||
|
||||
@@ -2,6 +2,7 @@ local BD = require("ui/bidi")
|
||||
local ConfirmBox = require("ui/widget/confirmbox")
|
||||
local DataStorage = require("datastorage")
|
||||
local Device = require("device")
|
||||
local Event = require("ui/event")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local LuaSettings = require("luasettings")
|
||||
local UIManager = require("ui/uimanager")
|
||||
@@ -16,38 +17,80 @@ function NetworkMgr:readNWSettings()
|
||||
self.nw_settings = LuaSettings:open(DataStorage:getSettingsDir().."/network.lua")
|
||||
end
|
||||
|
||||
-- Used after restoreWifiAsync() to make sure we eventually send a NetworkConnected event, as a few things rely on it (KOSync, c.f. #5109).
|
||||
function NetworkMgr:connectivityCheck(iter)
|
||||
-- Give up after a while...
|
||||
if iter > 6 then
|
||||
-- Used after restoreWifiAsync() and the turn_on beforeWifiAction to make sure we eventually send a NetworkConnected event,
|
||||
-- as quite a few things rely on it (KOSync, c.f. #5109; the network activity check, c.f., #6424).
|
||||
function NetworkMgr:connectivityCheck(iter, callback, widget)
|
||||
-- Give up after a while (restoreWifiAsync can take over 45s, so, try to cover that)...
|
||||
if iter > 25 then
|
||||
logger.info("Failed to restore Wi-Fi (after", iter, "iterations)!")
|
||||
self.wifi_was_on = false
|
||||
G_reader_settings:saveSetting("wifi_was_on", false)
|
||||
-- If we abort, murder Wi-Fi and the async script first...
|
||||
if Device:hasWifiManager() and not Device:isEmulator() then
|
||||
os.execute("pkill -TERM restore-wifi-async.sh 2>/dev/null")
|
||||
end
|
||||
NetworkMgr:turnOffWifi()
|
||||
|
||||
-- Handle the UI warning if it's from a beforeWifiAction...
|
||||
if widget then
|
||||
UIManager:close(widget)
|
||||
UIManager:show(InfoMessage:new{ text = _("Error connecting to the network") })
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if NetworkMgr:isWifiOn() and NetworkMgr:isConnected() then
|
||||
local Event = require("ui/event")
|
||||
self.wifi_was_on = true
|
||||
G_reader_settings:saveSetting("wifi_was_on", true)
|
||||
UIManager:broadcastEvent(Event:new("NetworkConnected"))
|
||||
logger.info("WiFi successfully restored!")
|
||||
logger.info("Wi-Fi successfully restored (after", iter, "iterations)!")
|
||||
|
||||
-- Handle the UI & callback if it's from a beforeWifiAction...
|
||||
if widget then
|
||||
UIManager:close(widget)
|
||||
end
|
||||
if callback then
|
||||
callback()
|
||||
else
|
||||
-- If this trickled down from a turn_onbeforeWifiAction and there is no callback,
|
||||
-- mention that the action needs to be retried manually.
|
||||
if widget then
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = _("You can now retry the action that required network access"),
|
||||
timeout = 3,
|
||||
})
|
||||
end
|
||||
end
|
||||
else
|
||||
UIManager:scheduleIn(2, function() NetworkMgr:connectivityCheck(iter + 1) end)
|
||||
UIManager:scheduleIn(2, function() NetworkMgr:connectivityCheck(iter + 1, callback, widget) end)
|
||||
end
|
||||
end
|
||||
|
||||
function NetworkMgr:scheduleConnectivityCheck()
|
||||
UIManager:scheduleIn(2, function() NetworkMgr:connectivityCheck(1) end)
|
||||
function NetworkMgr:scheduleConnectivityCheck(callback, widget)
|
||||
UIManager:scheduleIn(2, function() NetworkMgr:connectivityCheck(1, callback, widget) end)
|
||||
end
|
||||
|
||||
function NetworkMgr:init()
|
||||
-- On Kobo, kill WiFi if NetworkMgr:isWifiOn() and NOT NetworkMgr:isConnected()
|
||||
-- (i.e., if the launcher left the WiFi in an inconsistent state: modules loaded, but no route to gateway).
|
||||
-- On Kobo, kill Wi-Fi if NetworkMgr:isWifiOn() and NOT NetworkMgr:isConnected()
|
||||
-- (i.e., if the launcher left the Wi-Fi in an inconsistent state: modules loaded, but no route to gateway).
|
||||
if Device:isKobo() and self:isWifiOn() and not self:isConnected() then
|
||||
logger.info("Kobo WiFi: Left in an inconsistent state by launcher!")
|
||||
logger.info("Kobo Wi-Fi: Left in an inconsistent state by launcher!")
|
||||
self:turnOffWifi()
|
||||
end
|
||||
|
||||
self.wifi_was_on = G_reader_settings:isTrue("wifi_was_on")
|
||||
if self.wifi_was_on and G_reader_settings:isTrue("auto_restore_wifi") then
|
||||
self:restoreWifiAsync()
|
||||
-- Don't bother if WiFi is already up...
|
||||
if not (self:isWifiOn() and self:isConnected()) then
|
||||
self:restoreWifiAsync()
|
||||
end
|
||||
self:scheduleConnectivityCheck()
|
||||
else
|
||||
-- Trigger an initial NetworkConnected event if WiFi was already up when we were launched
|
||||
if NetworkMgr:isWifiOn() and NetworkMgr:isConnected() then
|
||||
-- NOTE: This needs to be delayed because NetworkListener is initialized slightly later by the FM/Reader app...
|
||||
UIManager:scheduleIn(2, function() UIManager:broadcastEvent(Event:new("NetworkConnected")) end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -57,6 +100,7 @@ end
|
||||
function NetworkMgr:turnOnWifi() end
|
||||
function NetworkMgr:turnOffWifi() end
|
||||
function NetworkMgr:isWifiOn() end
|
||||
function NetworkMgr:getNetworkInterfaceName() end
|
||||
function NetworkMgr:getNetworkList() end
|
||||
function NetworkMgr:getCurrentNetwork() end
|
||||
function NetworkMgr:authenticateNetwork() end
|
||||
@@ -92,32 +136,69 @@ function NetworkMgr:promptWifiOff(complete_callback)
|
||||
end
|
||||
|
||||
function NetworkMgr:turnOnWifiAndWaitForConnection(callback)
|
||||
NetworkMgr:turnOnWifi()
|
||||
local timeout = 30
|
||||
local retry_count = 0
|
||||
local info = InfoMessage:new{ text = T(_("Enabling Wi-Fi. Waiting for Internet connection…\nTimeout %1 seconds."), timeout)}
|
||||
local info = InfoMessage:new{ text = _("Connecting to Wi-Fi…") }
|
||||
UIManager:show(info)
|
||||
UIManager:forceRePaint()
|
||||
while not NetworkMgr:isOnline() and retry_count < timeout do
|
||||
ffiutil.sleep(1)
|
||||
retry_count = retry_count + 1
|
||||
|
||||
-- Don't bother if WiFi is already up...
|
||||
if not (self:isWifiOn() and self:isConnected()) then
|
||||
self:turnOnWifi()
|
||||
end
|
||||
UIManager:close(info)
|
||||
if retry_count == timeout then
|
||||
UIManager:show(InfoMessage:new{ text = _("Error connecting to the network") })
|
||||
return
|
||||
end
|
||||
if callback then callback() end
|
||||
|
||||
-- This will handle sending the proper Event, manage wifi_was_on, as well as tearing down Wi-Fi in case of failures,
|
||||
-- (i.e., much like getWifiToggleMenuTable).
|
||||
self:scheduleConnectivityCheck(callback, info)
|
||||
end
|
||||
|
||||
--- This quirky internal flag is used for the rare beforeWifiAction -> afterWifiAction brackets.
|
||||
function NetworkMgr:clearBeforeActionFlag()
|
||||
self._before_action_tripped = nil
|
||||
end
|
||||
|
||||
function NetworkMgr:setBeforeActionFlag()
|
||||
self._before_action_tripped = true
|
||||
end
|
||||
|
||||
function NetworkMgr:getBeforeActionFlag()
|
||||
return self._before_action_tripped
|
||||
end
|
||||
|
||||
--- @note: The callback will only run *after* a *succesful* network connection.
|
||||
--- The only guarantee it provides is isConnected (i.e., an IP & a local gateway),
|
||||
--- *NOT* isOnline (i.e., WAN), se be careful with recursive callbacks!
|
||||
function NetworkMgr:beforeWifiAction(callback)
|
||||
-- Remember that we ran, for afterWifiAction...
|
||||
self:setBeforeActionFlag()
|
||||
|
||||
local wifi_enable_action = G_reader_settings:readSetting("wifi_enable_action")
|
||||
if wifi_enable_action == "turn_on" then
|
||||
NetworkMgr:turnOnWifiAndWaitForConnection(callback)
|
||||
else
|
||||
NetworkMgr:promptWifiOn(callback)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- NOTE: This is actually used very sparingly (newsdownloader/send2ebook),
|
||||
-- because bracketing a single action in a connect/disconnect session doesn't necessarily make much sense...
|
||||
function NetworkMgr:afterWifiAction(callback)
|
||||
-- Don't do anything if beforeWifiAction never actually ran...
|
||||
if not self:getBeforeActionFlag() then
|
||||
return
|
||||
end
|
||||
self:clearBeforeActionFlag()
|
||||
|
||||
local wifi_disable_action = G_reader_settings:readSetting("wifi_disable_action")
|
||||
if wifi_disable_action == "leave_on" then
|
||||
-- NOP :)
|
||||
if callback then
|
||||
callback()
|
||||
end
|
||||
elseif wifi_disable_action == "turn_off" then
|
||||
NetworkMgr:turnOffWifi(callback)
|
||||
else
|
||||
NetworkMgr:promptWifiOff(callback)
|
||||
end
|
||||
end
|
||||
|
||||
function NetworkMgr:isConnected()
|
||||
if Device:isAndroid() or Device:isCervantes() or Device:isPocketBook() or Device:isEmulator() then
|
||||
@@ -174,6 +255,68 @@ function NetworkMgr:setHTTPProxy(proxy)
|
||||
end
|
||||
end
|
||||
|
||||
-- Helper functions to hide the quirks of using beforeWifiAction properly ;).
|
||||
|
||||
-- Run callback *now* if you're currently online (ie., isOnline),
|
||||
-- or attempt to go online and run it *ASAP* without any more user interaction.
|
||||
-- NOTE: If you're currently connected but without Internet access (i.e., isConnected and not isOnline),
|
||||
-- it will just attempt to re-connect, *without* running the callback.
|
||||
-- c.f., ReaderWikipedia:onShowWikipediaLookup @ frontend/apps/reader/modules/readerwikipedia.lua
|
||||
function NetworkMgr:runWhenOnline(callback)
|
||||
if self:isOnline() then
|
||||
callback()
|
||||
else
|
||||
--- @note: Avoid infinite recursion, beforeWifiAction only guarantees isConnected, not isOnline.
|
||||
if not self:isConnected() then
|
||||
self:beforeWifiAction(callback)
|
||||
else
|
||||
self:beforeWifiAction()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- This one is for callbacks that only require isConnected, and since that's guaranteed by beforeWifiAction,
|
||||
-- you also have a guarantee that the callback *will* run.
|
||||
function NetworkMgr:runWhenConnected(callback)
|
||||
if self:isConnected() then
|
||||
callback()
|
||||
else
|
||||
self:beforeWifiAction(callback)
|
||||
end
|
||||
end
|
||||
|
||||
-- Mild variants that are used for recursive calls at the beginning of a complex function call.
|
||||
-- Returns true when not yet online, in which case you should *abort* (i.e., return) the initial call,
|
||||
-- and otherwise, go-on as planned.
|
||||
-- NOTE: If you're currently connected but without Internet access (i.e., isConnected and not isOnline),
|
||||
-- it will just attempt to re-connect, *without* running the callback.
|
||||
-- c.f., ReaderWikipedia:lookupWikipedia @ frontend/apps/reader/modules/readerwikipedia.lua
|
||||
function NetworkMgr:willRerunWhenOnline(callback)
|
||||
if not self:isOnline() then
|
||||
--- @note: Avoid infinite recursion, beforeWifiAction only guarantees isConnected, not isOnline.
|
||||
if not self:isConnected() then
|
||||
self:beforeWifiAction(callback)
|
||||
else
|
||||
self:beforeWifiAction()
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- This one is for callbacks that only require isConnected, and since that's guaranteed by beforeWifiAction,
|
||||
-- you also have a guarantee that the callback *will* run.
|
||||
function NetworkMgr:willRerunWhenConnected(callback)
|
||||
if not self:isConnected() then
|
||||
self:beforeWifiAction(callback)
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function NetworkMgr:getWifiMenuTable()
|
||||
if Device:isAndroid() then
|
||||
return {
|
||||
@@ -196,7 +339,6 @@ function NetworkMgr:getWifiToggleMenuTable()
|
||||
local complete_callback = function()
|
||||
-- notify touch menu to update item check state
|
||||
touchmenu_instance:updateItems()
|
||||
local Event = require("ui/event")
|
||||
-- if wifi was on, this callback will only be executed when the network has been
|
||||
-- disconnected.
|
||||
if wifi_status then
|
||||
@@ -208,7 +350,7 @@ function NetworkMgr:getWifiToggleMenuTable()
|
||||
if NetworkMgr:isWifiOn() and NetworkMgr:isConnected() then
|
||||
UIManager:broadcastEvent(Event:new("NetworkConnected"))
|
||||
elseif NetworkMgr:isWifiOn() and not NetworkMgr:isConnected() then
|
||||
-- Don't leave WiFi in an inconsistent state if the connection failed.
|
||||
-- Don't leave Wi-Fi in an inconsistent state if the connection failed.
|
||||
self.wifi_was_on = false
|
||||
G_reader_settings:saveSetting("wifi_was_on", false)
|
||||
-- NOTE: We're limiting this to only a few platforms, as it might be actually harmful on some devices.
|
||||
@@ -219,8 +361,8 @@ function NetworkMgr:getWifiToggleMenuTable()
|
||||
-- Kobo: Yes, please.
|
||||
-- Cervantes: Loads/unloads module, probably could use it like Kobo.
|
||||
-- Kindle: Probably could use it, if only because leaving Wireless on is generally a terrible idea on Kindle,
|
||||
-- except that we defer to lipc, which makes WiFi handling asynchronous, and the callback is simply delayed by 1s,
|
||||
-- so we can't be sure the system will actually have finished bringing WiFi up by then...
|
||||
-- except that we defer to lipc, which makes Wi-Fi handling asynchronous, and the callback is simply delayed by 1s,
|
||||
-- so we can't be sure the system will actually have finished bringing Wi-Fi up by then...
|
||||
NetworkMgr:turnOffWifi()
|
||||
touchmenu_instance:updateItems()
|
||||
end
|
||||
@@ -276,9 +418,26 @@ function NetworkMgr:getProxyMenuTable()
|
||||
}
|
||||
end
|
||||
|
||||
function NetworkMgr:getPowersaveMenuTable()
|
||||
return {
|
||||
text = _("Kill Wi-Fi connection when inactive"),
|
||||
help_text = _([[This will automatically turn Wi-Fi off after a generous period of network inactivity, without disrupting workflows that require a network connection, so you can just keep reading without worrying about battery drain.]]),
|
||||
checked_func = function() return G_reader_settings:isTrue("auto_disable_wifi") end,
|
||||
enabled_func = function() return Device:hasWifiManager() and not Device:isEmulator() end,
|
||||
callback = function()
|
||||
G_reader_settings:flipNilOrFalse("auto_disable_wifi")
|
||||
-- NOTE: Well, not exactly, but the activity check wouldn't be (un)scheduled until the next Network(Dis)Connected event...
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = _("This will take effect on next restart."),
|
||||
})
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
function NetworkMgr:getRestoreMenuTable()
|
||||
return {
|
||||
text = _("Automatically restore Wi-Fi connection after resume"),
|
||||
text = _("Restore Wi-Fi connection on resume"),
|
||||
help_text = _([[This will attempt to automatically and silently re-connect to Wi-Fi on startup or on resume if Wi-Fi used to be enabled the last time you used KOReader.]]),
|
||||
checked_func = function() return G_reader_settings:isTrue("auto_restore_wifi") end,
|
||||
enabled_func = function() return Device:hasWifiManager() and not Device:isEmulator() end,
|
||||
callback = function() G_reader_settings:flipNilOrFalse("auto_restore_wifi") end,
|
||||
@@ -306,34 +465,67 @@ function NetworkMgr:getInfoMenuTable()
|
||||
end
|
||||
|
||||
function NetworkMgr:getBeforeWifiActionMenuTable()
|
||||
local wifi_enable_action_setting = G_reader_settings:readSetting("wifi_enable_action") or "prompt"
|
||||
local wifi_enable_actions = {
|
||||
turn_on = {_("turn on"), _("Turn on (experimental)")},
|
||||
prompt = {_("prompt"), _("Prompt")},
|
||||
}
|
||||
local action_table = function(wifi_enable_action)
|
||||
return {
|
||||
text = wifi_enable_actions[wifi_enable_action][2],
|
||||
checked_func = function()
|
||||
return wifi_enable_action_setting == wifi_enable_action
|
||||
end,
|
||||
callback = function()
|
||||
wifi_enable_action_setting = wifi_enable_action
|
||||
G_reader_settings:saveSetting("wifi_enable_action", wifi_enable_action)
|
||||
end,
|
||||
}
|
||||
end
|
||||
return {
|
||||
text_func = function()
|
||||
return T(_("Action when Wi-Fi is off: %1"),
|
||||
wifi_enable_actions[wifi_enable_action_setting][1]
|
||||
)
|
||||
end,
|
||||
sub_item_table = {
|
||||
action_table("turn_on"),
|
||||
action_table("prompt"),
|
||||
}
|
||||
}
|
||||
local wifi_enable_action_setting = G_reader_settings:readSetting("wifi_enable_action") or "prompt"
|
||||
local wifi_enable_actions = {
|
||||
turn_on = {_("turn on"), _("Turn on")},
|
||||
prompt = {_("prompt"), _("Prompt")},
|
||||
}
|
||||
local action_table = function(wifi_enable_action)
|
||||
return {
|
||||
text = wifi_enable_actions[wifi_enable_action][2],
|
||||
checked_func = function()
|
||||
return wifi_enable_action_setting == wifi_enable_action
|
||||
end,
|
||||
callback = function()
|
||||
wifi_enable_action_setting = wifi_enable_action
|
||||
G_reader_settings:saveSetting("wifi_enable_action", wifi_enable_action)
|
||||
end,
|
||||
}
|
||||
end
|
||||
return {
|
||||
text_func = function()
|
||||
return T(_("Action when Wi-Fi is off: %1"),
|
||||
wifi_enable_actions[wifi_enable_action_setting][1]
|
||||
)
|
||||
end,
|
||||
sub_item_table = {
|
||||
action_table("turn_on"),
|
||||
action_table("prompt"),
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function NetworkMgr:getAfterWifiActionMenuTable()
|
||||
local wifi_disable_action_setting = G_reader_settings:readSetting("wifi_disable_action") or "prompt"
|
||||
local wifi_disable_actions = {
|
||||
leave_on = {_("leave on"), _("Leave on")},
|
||||
turn_off = {_("turn off"), _("Turn off")},
|
||||
prompt = {_("prompt"), _("Prompt")},
|
||||
}
|
||||
local action_table = function(wifi_disable_action)
|
||||
return {
|
||||
text = wifi_disable_actions[wifi_disable_action][2],
|
||||
checked_func = function()
|
||||
return wifi_disable_action_setting == wifi_disable_action
|
||||
end,
|
||||
callback = function()
|
||||
wifi_disable_action_setting = wifi_disable_action
|
||||
G_reader_settings:saveSetting("wifi_disable_action", wifi_disable_action)
|
||||
end,
|
||||
}
|
||||
end
|
||||
return {
|
||||
text_func = function()
|
||||
return T(_("Action when done with Wi-Fi: %1"),
|
||||
wifi_disable_actions[wifi_disable_action_setting][1]
|
||||
)
|
||||
end,
|
||||
sub_item_table = {
|
||||
action_table("leave_on"),
|
||||
action_table("turn_off"),
|
||||
action_table("prompt"),
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function NetworkMgr:getDismissScanMenuTable()
|
||||
@@ -354,9 +546,11 @@ function NetworkMgr:getMenuTable(common_settings)
|
||||
common_settings.network_info = self:getInfoMenuTable()
|
||||
|
||||
if Device:hasWifiManager() then
|
||||
common_settings.network_powersave = self:getPowersaveMenuTable()
|
||||
common_settings.network_restore = self:getRestoreMenuTable()
|
||||
common_settings.network_dismiss_scan = self:getDismissScanMenuTable()
|
||||
common_settings.network_before_wifi_action = self:getBeforeWifiActionMenuTable()
|
||||
common_settings.network_after_wifi_action = self:getAfterWifiActionMenuTable()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -458,6 +652,7 @@ if NETWORK_PROXY then
|
||||
NetworkMgr:setHTTPProxy(NETWORK_PROXY)
|
||||
end
|
||||
|
||||
|
||||
Device:initNetworkManager(NetworkMgr)
|
||||
NetworkMgr:init()
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
local BD = require("ui/bidi")
|
||||
local Device = require("device")
|
||||
local Event = require("ui/event")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local InputContainer = require("ui/widget/container/inputcontainer")
|
||||
local NetworkMgr = require("ui/network/manager")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local logger = require("logger")
|
||||
local _ = require("gettext")
|
||||
local T = require("ffi/util").template
|
||||
|
||||
@@ -16,10 +19,17 @@ function NetworkListener:onToggleWifi()
|
||||
})
|
||||
|
||||
-- NB Normal widgets should use NetworkMgr:promptWifiOn()
|
||||
-- This is specifically the toggle wifi action, so consent is implied.
|
||||
NetworkMgr:turnOnWifi()
|
||||
-- (or, better yet, the NetworkMgr:beforeWifiAction wrappers: NetworkMgr:runWhenOnline() & co.)
|
||||
-- This is specifically the toggle Wi-Fi action, so consent is implied.
|
||||
local complete_callback = function()
|
||||
UIManager:broadcastEvent(Event:new("NetworkConnected"))
|
||||
end
|
||||
NetworkMgr:turnOnWifi(complete_callback)
|
||||
else
|
||||
NetworkMgr:turnOffWifi()
|
||||
local complete_callback = function()
|
||||
UIManager:broadcastEvent(Event:new("NetworkDisconnected"))
|
||||
end
|
||||
NetworkMgr:turnOffWifi(complete_callback)
|
||||
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = _("Wi-Fi off."),
|
||||
@@ -29,8 +39,11 @@ function NetworkListener:onToggleWifi()
|
||||
end
|
||||
|
||||
function NetworkListener:onInfoWifiOff()
|
||||
-- can't hurt
|
||||
NetworkMgr:turnOffWifi()
|
||||
-- That's the end goal
|
||||
local complete_callback = function()
|
||||
UIManager:broadcastEvent(Event:new("NetworkDisconnected"))
|
||||
end
|
||||
NetworkMgr:turnOffWifi(complete_callback)
|
||||
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = _("Wi-Fi off."),
|
||||
@@ -46,8 +59,12 @@ function NetworkListener:onInfoWifiOn()
|
||||
})
|
||||
|
||||
-- NB Normal widgets should use NetworkMgr:promptWifiOn()
|
||||
-- (or, better yet, the NetworkMgr:beforeWifiAction wrappers: NetworkMgr:runWhenOnline() & co.)
|
||||
-- This is specifically the toggle Wi-Fi action, so consent is implied.
|
||||
NetworkMgr:turnOnWifi()
|
||||
local complete_callback = function()
|
||||
UIManager:broadcastEvent(Event:new("NetworkConnected"))
|
||||
end
|
||||
NetworkMgr:turnOnWifi(complete_callback)
|
||||
else
|
||||
local info_text
|
||||
local current_network = NetworkMgr:getCurrentNetwork()
|
||||
@@ -64,4 +81,136 @@ function NetworkListener:onInfoWifiOn()
|
||||
end
|
||||
end
|
||||
|
||||
-- Everything below is to handle auto_disable_wifi ;).
|
||||
local default_network_timeout_seconds = 5*60
|
||||
local max_network_timeout_seconds = 30*60
|
||||
-- This should be more than enough to catch actual activity vs. noise spread over 5 minutes.
|
||||
local network_activity_noise_margin = 12 -- unscaled_size_check: ignore
|
||||
|
||||
-- Read the statistics/tx_packets sysfs entry for the current network interface.
|
||||
-- It *should* be the least noisy entry on an idle network...
|
||||
-- The fact that auto_disable_wifi is only available on (Device:hasWifiManager() and not Device:isEmulator())
|
||||
-- allows us to get away with a Linux-only solution.
|
||||
function NetworkListener:_getTxPackets()
|
||||
-- read tx_packets stats from sysfs (for the right network if)
|
||||
local file = io.open("/sys/class/net/" .. NetworkMgr:getNetworkInterfaceName() .. "/statistics/tx_packets", "rb")
|
||||
|
||||
-- file exists only when Wi-Fi module is loaded.
|
||||
if not file then return nil end
|
||||
|
||||
local out = file:read("*all")
|
||||
file:close()
|
||||
|
||||
-- strip NaN from file read (i.e.,: line endings, error messages)
|
||||
local tx_packets
|
||||
if type(out) ~= "number" then
|
||||
tx_packets = tonumber(out)
|
||||
else
|
||||
tx_packets = out
|
||||
end
|
||||
|
||||
-- finally return it
|
||||
if type(tx_packets) == "number" then
|
||||
return tx_packets
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
function NetworkListener:_unscheduleActivityCheck()
|
||||
logger.dbg("NetworkListener: unschedule network activity check")
|
||||
if self._activity_check_scheduled then
|
||||
UIManager:unschedule(self._scheduleActivityCheck)
|
||||
self._activity_check_scheduled = nil
|
||||
logger.dbg("NetworkListener: network activity check unscheduled")
|
||||
end
|
||||
|
||||
-- We also need to reset the stats, otherwise we'll be comparing apples vs. oranges... (i.e., two different network sessions)
|
||||
if self._last_tx_packets then
|
||||
self._last_tx_packets = nil
|
||||
end
|
||||
if self._activity_check_delay then
|
||||
self._activity_check_delay = nil
|
||||
end
|
||||
end
|
||||
|
||||
function NetworkListener:_scheduleActivityCheck()
|
||||
logger.dbg("NetworkListener: network activity check")
|
||||
local keep_checking = true
|
||||
|
||||
local tx_packets = NetworkListener:_getTxPackets()
|
||||
if self._last_tx_packets then
|
||||
-- Compute noise margin based on the current delay
|
||||
local delay = self._activity_check_delay or default_network_timeout_seconds
|
||||
local noise = delay / default_network_timeout_seconds * network_activity_noise_margin
|
||||
-- If there was no meaningful activity (+/- a couple packets), kill the Wi-Fi
|
||||
if math.max(0, tx_packets - noise) <= self._last_tx_packets then
|
||||
logger.dbg("NetworkListener: No meaningful network activity ( then:", self._last_tx_packets, "vs. now:", tx_packets, "), disabling Wi-Fi")
|
||||
keep_checking = false
|
||||
local complete_callback = function()
|
||||
UIManager:broadcastEvent(Event:new("NetworkDisconnected"))
|
||||
end
|
||||
NetworkMgr:turnOffWifi(complete_callback)
|
||||
-- NOTE: We leave wifi_was_on as-is on purpose, we wouldn't want to break auto_restore_wifi workflows on the next start...
|
||||
end
|
||||
end
|
||||
|
||||
-- If we've just killed Wi-Fi, onNetworkDisconnected will take care of unscheduling us
|
||||
if keep_checking then
|
||||
-- Update tracker for next iter
|
||||
self._last_tx_packets = tx_packets
|
||||
|
||||
-- If it's already been scheduled, increase the delay until we hit the ceiling
|
||||
if self._activity_check_delay then
|
||||
self._activity_check_delay = self._activity_check_delay + default_network_timeout_seconds
|
||||
|
||||
if self._activity_check_delay > max_network_timeout_seconds then
|
||||
self._activity_check_delay = max_network_timeout_seconds
|
||||
end
|
||||
else
|
||||
self._activity_check_delay = default_network_timeout_seconds
|
||||
end
|
||||
|
||||
UIManager:scheduleIn(self._activity_check_delay, self._scheduleActivityCheck, self)
|
||||
self._activity_check_scheduled = true
|
||||
logger.dbg("NetworkListener: network activity check scheduled in", self._activity_check_delay, "seconds")
|
||||
end
|
||||
end
|
||||
|
||||
function NetworkListener:onNetworkConnected()
|
||||
if not (Device:hasWifiManager() and not Device:isEmulator()) then
|
||||
return
|
||||
end
|
||||
|
||||
if not G_reader_settings:isTrue("auto_disable_wifi") then
|
||||
return
|
||||
end
|
||||
|
||||
-- If the activity check has already been scheduled for some reason, unschedule it first.
|
||||
NetworkListener:_unscheduleActivityCheck()
|
||||
|
||||
NetworkListener:_scheduleActivityCheck()
|
||||
end
|
||||
|
||||
function NetworkListener:onNetworkDisconnected()
|
||||
if not (Device:hasWifiManager() and not Device:isEmulator()) then
|
||||
return
|
||||
end
|
||||
|
||||
if not G_reader_settings:isTrue("auto_disable_wifi") then
|
||||
return
|
||||
end
|
||||
|
||||
NetworkListener:_unscheduleActivityCheck()
|
||||
|
||||
-- Reset NetworkMgr's beforeWifiAction marker
|
||||
NetworkMgr:clearBeforeActionFlag()
|
||||
end
|
||||
|
||||
-- Also unschedule on suspend (and we happen to also kill Wi-Fi to do so, so resetting the stats is also relevant here)
|
||||
function NetworkListener:onSuspend()
|
||||
self:onNetworkDisconnected()
|
||||
end
|
||||
|
||||
|
||||
return NetworkListener
|
||||
|
||||
@@ -455,21 +455,19 @@ function OTAManager:getOTAMenuTable()
|
||||
return {
|
||||
text = _("Update"),
|
||||
hold_callback = function()
|
||||
if not NetworkMgr:isOnline() then
|
||||
NetworkMgr:promptWifiOn()
|
||||
else
|
||||
local connect_callback = function()
|
||||
OTAManager:fetchAndProcessUpdate()
|
||||
end
|
||||
NetworkMgr:runWhenOnline(connect_callback)
|
||||
end,
|
||||
sub_item_table = {
|
||||
{
|
||||
text = _("Check for update"),
|
||||
callback = function()
|
||||
if not NetworkMgr:isOnline() then
|
||||
NetworkMgr:promptWifiOn()
|
||||
else
|
||||
local connect_callback = function()
|
||||
OTAManager:fetchAndProcessUpdate()
|
||||
end
|
||||
NetworkMgr:runWhenOnline(connect_callback)
|
||||
end
|
||||
},
|
||||
{
|
||||
|
||||
@@ -416,10 +416,10 @@ Show translated text in TextViewer, with alternate translations
|
||||
--]]
|
||||
function Translator:showTranslation(text, target_lang, source_lang)
|
||||
local NetworkMgr = require("ui/network/manager")
|
||||
if not NetworkMgr:isOnline() then
|
||||
NetworkMgr:promptWifiOn()
|
||||
if NetworkMgr:willRerunWhenOnline(function() self:showTranslation(text, target_lang, source_lang) end) then
|
||||
return
|
||||
end
|
||||
|
||||
-- Wrap next function with Trapper to be able to interrupt
|
||||
-- translation service query.
|
||||
local Trapper = require("ui/trapper")
|
||||
|
||||
@@ -22,9 +22,12 @@ Example:
|
||||
UIManager:show(require("ui/widget/networksetting"):new{
|
||||
network_list = network_list,
|
||||
connect_callback = function()
|
||||
-- connect_callback will be called when an connect/disconnect
|
||||
-- attempt has been made. you can update UI widgets in the
|
||||
-- callback.
|
||||
-- connect_callback will be called when a *connect* (NOT disconnect)
|
||||
-- attempt has been successful.
|
||||
-- You can update UI widgets in the callback.
|
||||
end,
|
||||
disconnect_callback = function()
|
||||
-- This one will fire unconditionally after a disconnect attempt.
|
||||
end,
|
||||
})
|
||||
|
||||
@@ -224,7 +227,8 @@ function NetworkItem:connect()
|
||||
text = err_msg
|
||||
end
|
||||
|
||||
if self.setting_ui.connect_callback then
|
||||
-- Do what it says on the tin, and only trigger the connect_callback on a *successful* connect.
|
||||
if success and self.setting_ui.connect_callback then
|
||||
self.setting_ui.connect_callback()
|
||||
end
|
||||
|
||||
@@ -244,8 +248,8 @@ function NetworkItem:disconnect()
|
||||
self.info.connected = nil
|
||||
self:refresh()
|
||||
self.setting_ui:setConnectedItem(nil)
|
||||
if self.setting_ui.connect_callback then
|
||||
self.setting_ui.connect_callback()
|
||||
if self.setting_ui.disconnect_callback then
|
||||
self.setting_ui.disconnect_callback()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -378,6 +382,7 @@ local NetworkSetting = InputContainer:new{
|
||||
-- }
|
||||
network_list = nil,
|
||||
connect_callback = nil,
|
||||
disconnect_callback = nil,
|
||||
}
|
||||
|
||||
function NetworkSetting:init()
|
||||
|
||||
@@ -377,10 +377,7 @@ end
|
||||
|
||||
function OPDSBrowser:getCatalog(item_url, username, password)
|
||||
local ok, catalog = pcall(self.parseFeed, self, item_url, username, password)
|
||||
if not ok and catalog and not NetworkMgr:isOnline() then
|
||||
NetworkMgr:promptWifiOn()
|
||||
return
|
||||
elseif not ok and catalog then
|
||||
if not ok and catalog then
|
||||
logger.info("cannot get catalog info from", item_url, catalog)
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = T(_("Cannot get catalog info from %1"), (BD.url(item_url) or "")),
|
||||
@@ -724,11 +721,17 @@ function OPDSBrowser:onMenuSelect(item)
|
||||
self:showDownloads(item)
|
||||
-- navigation
|
||||
else
|
||||
local connect_callback
|
||||
if item.searchable then
|
||||
self:browseSearchable(item.url, item.username, item.password)
|
||||
connect_callback = function()
|
||||
self:browseSearchable(item.url, item.username, item.password)
|
||||
end
|
||||
else
|
||||
self:browse(item.url, item.username, item.password)
|
||||
connect_callback = function()
|
||||
self:browse(item.url, item.username, item.password)
|
||||
end
|
||||
end
|
||||
NetworkMgr:runWhenConnected(connect_callback)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -21,11 +21,11 @@ EOF
|
||||
}
|
||||
|
||||
RestoreWifi() {
|
||||
echo "[$(date)] restore-wifi-async.sh: Restarting WiFi"
|
||||
echo "[$(date)] restore-wifi-async.sh: Restarting Wi-Fi"
|
||||
./enable-wifi.sh
|
||||
RunWpaCli
|
||||
./obtain-ip.sh
|
||||
echo "[$(date)] restore-wifi-async.sh: Restarted WiFi"
|
||||
echo "[$(date)] restore-wifi-async.sh: Restarted Wi-Fi"
|
||||
}
|
||||
|
||||
RestoreWifi &
|
||||
|
||||
@@ -1,8 +1,38 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Disable wifi, and remove all modules.
|
||||
# NOTE: Save our resolv.conf to avoid ending up with an empty one, in case the DHCP client wipes it on release (#6424).
|
||||
cp -a "/etc/resolv.conf" "/tmp/resolv.ko"
|
||||
old_hash="$(md5sum "/etc/resolv.conf" | cut -f1 -d' ')"
|
||||
|
||||
killall udhcpc default.script wpa_supplicant 2>/dev/null
|
||||
if [ -x "/sbin/dhcpcd" ]; then
|
||||
env -u LD_LIBRARY_PATH dhcpcd -d -k "${INTERFACE}"
|
||||
killall -q -TERM udhcpc default.script
|
||||
else
|
||||
killall -q -TERM udhcpc default.script dhcpcd
|
||||
fi
|
||||
|
||||
# NOTE: dhcpcd -k waits for the signalled process to die, but busybox's killall doesn't have a -w, --wait flag,
|
||||
# so we have to wait for udhcpc to die ourselves...
|
||||
kill_timeout=0
|
||||
while pkill -0 udhcpc; do
|
||||
# Stop waiting after 5s
|
||||
if [ ${kill_timeout} -ge 20 ]; then
|
||||
break
|
||||
fi
|
||||
usleep 250000
|
||||
kill_timeout=$((kill_timeout + 1))
|
||||
done
|
||||
|
||||
new_hash="$(md5sum "/etc/resolv.conf" | cut -f1 -d' ')"
|
||||
# Restore our network-specific resolv.conf if the DHCP client wiped it when releasing the lease...
|
||||
if [ "${new_hash}" != "${old_hash}" ]; then
|
||||
mv -f "/tmp/resolv.ko" "/etc/resolv.conf"
|
||||
else
|
||||
rm -f "/tmp/resolv.ko"
|
||||
fi
|
||||
|
||||
wpa_cli terminate
|
||||
|
||||
[ "${WIFI_MODULE}" != "8189fs" ] && [ "${WIFI_MODULE}" != "8192es" ] && wlarm_le -i "${INTERFACE}" down
|
||||
ifconfig "${INTERFACE}" down
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Load wifi modules and enable wifi.
|
||||
|
||||
lsmod | grep -q sdio_wifi_pwr || insmod "/drivers/${PLATFORM}/wifi/sdio_wifi_pwr.ko"
|
||||
# Moar sleep!
|
||||
usleep 250000
|
||||
@@ -13,6 +12,6 @@ sleep 1
|
||||
ifconfig "${INTERFACE}" up
|
||||
[ "${WIFI_MODULE}" != "8189fs" ] && [ "${WIFI_MODULE}" != "8192es" ] && wlarm_le -i "${INTERFACE}" up
|
||||
|
||||
pidof wpa_supplicant >/dev/null ||
|
||||
pkill -0 wpa_supplicant ||
|
||||
env -u LD_LIBRARY_PATH \
|
||||
wpa_supplicant -D wext -s -i "${INTERFACE}" -O /var/run/wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant.conf -B
|
||||
wpa_supplicant -D wext -s -i "${INTERFACE}" -c /etc/wpa_supplicant/wpa_supplicant.conf -O /var/run/wpa_supplicant -B
|
||||
|
||||
@@ -110,7 +110,11 @@ if [ "${VIA_NICKEL}" = "true" ]; then
|
||||
sync
|
||||
# And we can now stop the full Kobo software stack
|
||||
# NOTE: We don't need to kill KFMon, it's smart enough not to allow running anything else while we're up
|
||||
killall -TERM nickel hindenburg sickel fickel adobehost fmon 2>/dev/null
|
||||
# NOTE: We kill Nickel's master dhcpcd daemon on purpose,
|
||||
# as we want to be able to use our own per-if processes w/ custom args later on.
|
||||
# A SIGTERM does not break anything, it'll just prevent automatic lease renewal until the time
|
||||
# KOReader actually sets the if up itself (i.e., it'll do)...
|
||||
killall -q -TERM nickel hindenburg sickel fickel adobehost dhcpcd-dbus dhcpcd fmon
|
||||
fi
|
||||
|
||||
# fallback for old fmon, KFMon and advboot users (-> if no args were passed to the script, start the FM)
|
||||
@@ -131,7 +135,7 @@ if [ -z "${PRODUCT}" ]; then
|
||||
export PRODUCT
|
||||
fi
|
||||
|
||||
# PLATFORM is used in koreader for the path to the WiFi drivers (as well as when restarting nickel)
|
||||
# PLATFORM is used in koreader for the path to the Wi-Fi drivers (as well as when restarting nickel)
|
||||
if [ -z "${PLATFORM}" ]; then
|
||||
# shellcheck disable=SC2046
|
||||
export $(grep -s -e '^PLATFORM=' "/proc/$(pidof -s udevd)/environ")
|
||||
@@ -209,6 +213,16 @@ ko_do_fbdepth() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Ensure we start with a valid nameserver in resolv.conf, otherwise we're stuck with broken name resolution (#6421, #6424).
|
||||
# Fun fact: this wouldn't be necessary if Kobo were using a non-prehistoric glibc... (it was fixed in glibc 2.26).
|
||||
ko_do_dns() {
|
||||
# If there aren't any servers listed, append CloudFlare's
|
||||
if not grep -q '^nameserver' "/etc/resolv.conf"; then
|
||||
echo "# Added by KOReader because your setup is broken" >>"/etc/resolv.conf"
|
||||
echo "nameserver 1.1.1.1" >>"/etc/resolv.conf"
|
||||
fi
|
||||
}
|
||||
|
||||
# Remount the SD card RW if it's inserted and currently RO
|
||||
if awk '$4~/(^|,)ro($|,)/' /proc/mounts | grep ' /mnt/sd '; then
|
||||
mount -o remount,rw /mnt/sd
|
||||
@@ -232,6 +246,8 @@ while [ ${RETURN_VALUE} -ne 0 ]; do
|
||||
ko_update_check
|
||||
# Do or double-check the fb depth switch, or restore original bitdepth if requested
|
||||
ko_do_fbdepth
|
||||
# Make sure we have a sane resolv.conf
|
||||
ko_do_dns
|
||||
fi
|
||||
|
||||
./reader.lua "${args}" >>crash.log 2>&1
|
||||
@@ -273,11 +289,11 @@ while [ ${RETURN_VALUE} -ne 0 ]; do
|
||||
fi
|
||||
# U+1F4A3, the hard way, because we can't use \u or \U escape sequences...
|
||||
# shellcheck disable=SC2039
|
||||
./fbink -q -b -O -m -t regular=./fonts/freefont/FreeSerif.ttf,px=${bombHeight},top=${bombMargin} $'\xf0\x9f\x92\xa3'
|
||||
./fbink -q -b -O -m -t regular=./fonts/freefont/FreeSerif.ttf,px=${bombHeight},top=${bombMargin} -- $'\xf0\x9f\x92\xa3'
|
||||
# And then print the tail end of the log on the bottom of the screen...
|
||||
crashLog="$(tail -n 25 crash.log | sed -e 's/\t/ /g')"
|
||||
# The idea for the margins being to leave enough room for an fbink -Z bar, small horizontal margins, and a font size based on what 6pt looked like @ 265dpi
|
||||
./fbink -q -b -O -t regular=./fonts/droid/DroidSansMono.ttf,top=$((viewHeight / 2 + FONTH * 2 + FONTH / 2)),left=$((viewWidth / 60)),right=$((viewWidth / 60)),px=$((viewHeight / 64)) "${crashLog}"
|
||||
./fbink -q -b -O -t regular=./fonts/droid/DroidSansMono.ttf,top=$((viewHeight / 2 + FONTH * 2 + FONTH / 2)),left=$((viewWidth / 60)),right=$((viewWidth / 60)),px=$((viewHeight / 64)) -- "${crashLog}"
|
||||
# So far, we hadn't triggered an actual screen refresh, do that now, to make sure everything is bundled in a single flashing refresh.
|
||||
./fbink -q -f -s
|
||||
# Cue a lemming's faceplant sound effect!
|
||||
|
||||
@@ -21,10 +21,38 @@ unset KO_NO_CBB
|
||||
/etc/init.d/on-animator.sh
|
||||
) &
|
||||
|
||||
# Make sure we kill the WiFi first, because nickel apparently doesn't like it if it's up... (cf. #1520)
|
||||
# Make sure we kill the Wi-Fi first, because nickel apparently doesn't like it if it's up... (cf. #1520)
|
||||
# NOTE: That check is possibly wrong on PLATFORM == freescale (because I don't know if the sdio_wifi_pwr module exists there), but we don't terribly care about that.
|
||||
if lsmod | grep -q sdio_wifi_pwr; then
|
||||
killall restore-wifi-async.sh enable-wifi.sh obtain-ip.sh udhcpc default.script wpa_supplicant 2>/dev/null
|
||||
killall -q -TERM restore-wifi-async.sh enable-wifi.sh obtain-ip.sh
|
||||
cp -a "/etc/resolv.conf" "/tmp/resolv.ko"
|
||||
old_hash="$(md5sum "/etc/resolv.conf" | cut -f1 -d' ')"
|
||||
if [ -x "/sbin/dhcpcd" ]; then
|
||||
env -u LD_LIBRARY_PATH dhcpcd -d -k "${INTERFACE}"
|
||||
killall -q -TERM udhcpc default.script
|
||||
else
|
||||
killall -q -TERM udhcpc default.script dhcpcd
|
||||
fi
|
||||
# NOTE: dhcpcd -k waits for the signalled process to die, but busybox's killall doesn't have a -w, --wait flag,
|
||||
# so we have to wait for udhcpc to die ourselves...
|
||||
kill_timeout=0
|
||||
while pkill -0 udhcpc; do
|
||||
# Stop waiting after 5s
|
||||
if [ ${kill_timeout} -ge 20 ]; then
|
||||
break
|
||||
fi
|
||||
usleep 250000
|
||||
kill_timeout=$((kill_timeout + 1))
|
||||
done
|
||||
|
||||
new_hash="$(md5sum "/etc/resolv.conf" | cut -f1 -d' ')"
|
||||
# Restore our network-specific resolv.conf if the DHCP client wiped it when releasing the lease...
|
||||
if [ "${new_hash}" != "${old_hash}" ]; then
|
||||
mv -f "/tmp/resolv.ko" "/etc/resolv.conf"
|
||||
else
|
||||
rm -f "/tmp/resolv.ko"
|
||||
fi
|
||||
wpa_cli terminate
|
||||
[ "${WIFI_MODULE}" != "8189fs" ] && [ "${WIFI_MODULE}" != "8192es" ] && wlarm_le -i "${INTERFACE}" down
|
||||
ifconfig "${INTERFACE}" down
|
||||
# NOTE: Kobo's busybox build is weird. rmmod appears to be modprobe in disguise, defaulting to the -r flag...
|
||||
|
||||
@@ -2,5 +2,10 @@
|
||||
|
||||
./release-ip.sh
|
||||
|
||||
# Use udhcpc to obtain IP.
|
||||
env -u LD_LIBRARY_PATH udhcpc -S -i "${INTERFACE}" -s /etc/udhcpc.d/default.script -t15 -T10 -A3 -b -q
|
||||
# NOTE: Prefer dhcpcd over udhcpc if available. That's what Nickel uses,
|
||||
# and udhcpc appears to trip some insanely wonky corner cases on current FW (#6421)
|
||||
if [ -x "/sbin/dhcpcd" ]; then
|
||||
env -u LD_LIBRARY_PATH dhcpcd -d -t 30 -w "${INTERFACE}"
|
||||
else
|
||||
env -u LD_LIBRARY_PATH udhcpc -S -i "${INTERFACE}" -s /etc/udhcpc.d/default.script -b -q
|
||||
fi
|
||||
|
||||
@@ -1,8 +1,34 @@
|
||||
#!/bin/sh
|
||||
|
||||
# PATH export is only needed if you run this script manually from a shell
|
||||
export PATH="${PATH}:/sbin"
|
||||
|
||||
# Release IP and shutdown udhcpc.
|
||||
pkill -9 -f '/bin/sh /etc/udhcpc.d/default.script'
|
||||
ifconfig "${INTERFACE}" 0.0.0.0
|
||||
# NOTE: Save our resolv.conf to avoid ending up with an empty one, in case the DHCP client wipes it on release (#6424).
|
||||
cp -a "/etc/resolv.conf" "/tmp/resolv.ko"
|
||||
old_hash="$(md5sum "/etc/resolv.conf" | cut -f1 -d' ')"
|
||||
|
||||
if [ -x "/sbin/dhcpcd" ]; then
|
||||
env -u LD_LIBRARY_PATH dhcpcd -d -k "${INTERFACE}"
|
||||
killall -q -TERM udhcpc default.script
|
||||
else
|
||||
killall -q -TERM udhcpc default.script dhcpcd
|
||||
ifconfig "${INTERFACE}" 0.0.0.0
|
||||
fi
|
||||
|
||||
# NOTE: dhcpcd -k waits for the signalled process to die, but busybox's killall doesn't have a -w, --wait flag,
|
||||
# so we have to wait for udhcpc to die ourselves...
|
||||
kill_timeout=0
|
||||
while pkill -0 udhcpc; do
|
||||
# Stop waiting after 5s
|
||||
if [ ${kill_timeout} -ge 20 ]; then
|
||||
break
|
||||
fi
|
||||
usleep 250000
|
||||
kill_timeout=$((kill_timeout + 1))
|
||||
done
|
||||
|
||||
new_hash="$(md5sum "/etc/resolv.conf" | cut -f1 -d' ')"
|
||||
# Restore our network-specific resolv.conf if the DHCP client wiped it when releasing the lease...
|
||||
if [ "${new_hash}" != "${old_hash}" ]; then
|
||||
mv -f "/tmp/resolv.ko" "/etc/resolv.conf"
|
||||
else
|
||||
rm -f "/tmp/resolv.ko"
|
||||
fi
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
RestoreWifi() {
|
||||
echo "[$(date)] restore-wifi-async.sh: Restarting WiFi"
|
||||
echo "[$(date)] restore-wifi-async.sh: Restarting Wi-Fi"
|
||||
|
||||
./enable-wifi.sh
|
||||
|
||||
@@ -9,8 +9,8 @@ RestoreWifi() {
|
||||
# Pilfered from https://github.com/shermp/Kobo-UNCaGED/pull/21 ;)
|
||||
wpac_timeout=0
|
||||
while ! wpa_cli status | grep -q "wpa_state=COMPLETED"; do
|
||||
# If wpa_supplicant hasn't connected within 10 seconds, assume it never will, and tear down WiFi
|
||||
if [ ${wpac_timeout} -ge 40 ]; then
|
||||
# If wpa_supplicant hasn't connected within 15 seconds, assume it never will, and tear down Wi-Fi
|
||||
if [ ${wpac_timeout} -ge 60 ]; then
|
||||
echo "[$(date)] restore-wifi-async.sh: Failed to connect to preferred AP!"
|
||||
./disable-wifi.sh
|
||||
return 1
|
||||
@@ -21,7 +21,7 @@ RestoreWifi() {
|
||||
|
||||
./obtain-ip.sh
|
||||
|
||||
echo "[$(date)] restore-wifi-async.sh: Restarted WiFi"
|
||||
echo "[$(date)] restore-wifi-async.sh: Restarted Wi-Fi"
|
||||
}
|
||||
|
||||
RestoreWifi &
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# General
|
||||
|
||||
When connected to WiFi you can find the IP address and root password for your
|
||||
When connected to Wi-Fi you can find the IP address and root password for your
|
||||
reMarkable in Settings -> About, then scroll down the GPLv3 compliance on the
|
||||
right (finger drag scroll, not the page forward/back buttons). This should also
|
||||
work for the USB network you get if you connect the reMarkable to your computer
|
||||
|
||||
@@ -178,11 +178,11 @@ while [ ${RETURN_VALUE} -ne 0 ]; do
|
||||
fi
|
||||
# U+1F4A3, the hard way, because we can't use \u or \U escape sequences...
|
||||
# shellcheck disable=SC2039
|
||||
./fbink -q -b -O -m -t regular=./fonts/freefont/FreeSerif.ttf,px=${bombHeight},top=${bombMargin} $'\xf0\x9f\x92\xa3'
|
||||
./fbink -q -b -O -m -t regular=./fonts/freefont/FreeSerif.ttf,px=${bombHeight},top=${bombMargin} -- $'\xf0\x9f\x92\xa3'
|
||||
# And then print the tail end of the log on the bottom of the screen...
|
||||
crashLog="$(tail -n 25 crash.log | sed -e 's/\t/ /g')"
|
||||
# The idea for the margins being to leave enough room for an fbink -Z bar, small horizontal margins, and a font size based on what 6pt looked like @ 265dpi
|
||||
./fbink -q -b -O -t regular=./fonts/droid/DroidSansMono.ttf,top=$((viewHeight / 2 + FONTH * 2 + FONTH / 2)),left=$((viewWidth / 60)),right=$((viewWidth / 60)),px=$((viewHeight / 64)) "${crashLog}"
|
||||
./fbink -q -b -O -t regular=./fonts/droid/DroidSansMono.ttf,top=$((viewHeight / 2 + FONTH * 2 + FONTH / 2)),left=$((viewWidth / 60)),right=$((viewWidth / 60)),px=$((viewHeight / 64)) -- "${crashLog}"
|
||||
# So far, we hadn't triggered an actual screen refresh, do that now, to make sure everything is bundled in a single flashing refresh.
|
||||
./fbink -q -f -s
|
||||
# Cue a lemming's faceplant sound effect!
|
||||
|
||||
@@ -5,9 +5,9 @@ if [ "$1" = "on" ]; then
|
||||
wmiconfig -i wlan0 --wlan enable
|
||||
wmiconfig -i wlan0 --setreassocmode 0
|
||||
wmiconfig -i wlan0 --power maxperf
|
||||
echo "WiFi Enabled"
|
||||
echo "Wi-Fi Enabled"
|
||||
else
|
||||
wmiconfig -i wlan0 --abortscan
|
||||
wmiconfig -i wlan0 --wlan disable
|
||||
echo "Wifi Disabled"
|
||||
echo "Wi-Fi Disabled"
|
||||
fi
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
set -x
|
||||
|
||||
# disable WiFi
|
||||
# disable Wi-Fi
|
||||
./set-wifi.sh off
|
||||
|
||||
# enter sleep, disabling all devices except CPU
|
||||
|
||||
@@ -203,6 +203,10 @@ Do you want to continue? ]]), driver),
|
||||
end
|
||||
|
||||
function CalibreWireless:connect()
|
||||
if NetworkMgr:willRerunWhenConnected(function() self:connect() end) then
|
||||
return
|
||||
end
|
||||
|
||||
self.connect_message = false
|
||||
local host, port
|
||||
if G_reader_settings:hasNot("calibre_wireless_url") then
|
||||
@@ -231,8 +235,6 @@ function CalibreWireless:connect()
|
||||
else
|
||||
self:setInboxDir(host, port)
|
||||
end
|
||||
elseif not NetworkMgr:isConnected() then
|
||||
NetworkMgr:promptWifiOn()
|
||||
else
|
||||
logger.info("cannot connect to calibre server")
|
||||
UIManager:show(InfoMessage:new{
|
||||
|
||||
@@ -347,10 +347,10 @@ For more information, please visit https://github.com/koreader/koreader/wiki/Eve
|
||||
end
|
||||
|
||||
function EvernoteExporter:login()
|
||||
if not NetworkMgr:isOnline() then
|
||||
NetworkMgr:promptWifiOn()
|
||||
if NetworkMgr:willRerunWhenOnline(function() self:login() end) then
|
||||
return
|
||||
end
|
||||
|
||||
self.login_dialog = LoginDialog:new{
|
||||
title = self.login_title,
|
||||
username = self.evernote_username or "",
|
||||
@@ -410,7 +410,7 @@ function EvernoteExporter:doLogin(username, password)
|
||||
}
|
||||
self.evernote_username = username
|
||||
local ok, token = pcall(oauth.getToken, oauth)
|
||||
-- prompt users to turn on Wifi if network is unreachable
|
||||
-- prompt users to turn on Wi-Fi if network is unreachable
|
||||
if not ok and token then
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = _("An error occurred while logging in:") .. "\n" .. token,
|
||||
@@ -425,7 +425,8 @@ function EvernoteExporter:doLogin(username, password)
|
||||
local guid
|
||||
ok, guid = pcall(self.getExportNotebook, self, client)
|
||||
if not ok and guid and guid:find("Transport not open") then
|
||||
NetworkMgr:promptWifiOn()
|
||||
--- @note: No recursive callback because it feels fishy here...
|
||||
NetworkMgr:beforeWifiAction()
|
||||
return
|
||||
elseif not ok and guid then
|
||||
UIManager:show(InfoMessage:new{
|
||||
@@ -589,7 +590,7 @@ function EvernoteExporter:exportClippings(clippings)
|
||||
end
|
||||
-- check if booknotes are exported in this notebook
|
||||
-- so that booknotes will still be exported after switching user account
|
||||
--Don't respect exported_stamp on txt export since it isn't possible to delete(update) prior clippings.
|
||||
-- Don't respect exported_stamp on txt export since it isn't possible to delete(update) prior clippings.
|
||||
if booknotes.exported[exported_stamp] ~= true or self.txt_export or self.json_export then
|
||||
local ok, err
|
||||
if self.html_export then
|
||||
@@ -603,9 +604,10 @@ function EvernoteExporter:exportClippings(clippings)
|
||||
else
|
||||
ok, err = pcall(self.exportBooknotesToEvernote, self, client, title, booknotes)
|
||||
end
|
||||
-- error reporting
|
||||
-- Error reporting
|
||||
if not ok and err and err:find("Transport not open") then
|
||||
NetworkMgr:promptWifiOn()
|
||||
--- @note: No recursive callback because it feels fishy here...
|
||||
NetworkMgr:beforeWifiAction()
|
||||
return
|
||||
elseif not ok and err then
|
||||
logger.dbg("Error while exporting book", title, err)
|
||||
|
||||
@@ -170,16 +170,16 @@ end
|
||||
-- search_type = author - serch book by author
|
||||
-- search_type = title - search book by title
|
||||
function Goodreads:search(search_type)
|
||||
if NetworkMgr:willRerunWhenOnline(function() self:search(search_type) end) then
|
||||
return
|
||||
end
|
||||
|
||||
local title_header
|
||||
local hint
|
||||
local search_input
|
||||
local text_input
|
||||
local info
|
||||
local result
|
||||
if not NetworkMgr:isOnline() then
|
||||
NetworkMgr:promptWifiOn()
|
||||
return
|
||||
end
|
||||
if search_type == "all" then
|
||||
title_header = _("Search all books in Goodreads")
|
||||
hint = _("Title, author or ISBN")
|
||||
|
||||
@@ -295,10 +295,10 @@ function KOSync:setWhisperBackward(strategy)
|
||||
end
|
||||
|
||||
function KOSync:login()
|
||||
if not NetworkMgr:isOnline() then
|
||||
NetworkMgr:promptWifiOn()
|
||||
if NetworkMgr:willRerunWhenOnline(function() self:login() end) then
|
||||
return
|
||||
end
|
||||
|
||||
self.login_dialog = LoginDialog:new{
|
||||
title = self.title,
|
||||
username = self.kosync_username or "",
|
||||
|
||||
@@ -22,7 +22,6 @@ local NewsDownloader = WidgetContainer:new{
|
||||
}
|
||||
|
||||
local initialized = false
|
||||
local wifi_enabled_before_action = true
|
||||
local feed_config_file_name = "feed_config.lua"
|
||||
local news_downloader_config_file = "news_downloader_settings.lua"
|
||||
local news_downloader_settings
|
||||
@@ -59,13 +58,6 @@ local function getFeedLink(possible_link)
|
||||
end
|
||||
end
|
||||
|
||||
--- @todo Implement as NetworkMgr:afterWifiAction with configuration options.
|
||||
function NewsDownloader:afterWifiAction()
|
||||
if not wifi_enabled_before_action then
|
||||
NetworkMgr:promptWifiOff()
|
||||
end
|
||||
end
|
||||
|
||||
function NewsDownloader:init()
|
||||
self.ui.menu:registerToMainMenu(self)
|
||||
end
|
||||
@@ -79,12 +71,7 @@ function NewsDownloader:addToMainMenu(menu_items)
|
||||
text = _("Download news"),
|
||||
keep_menu_open = true,
|
||||
callback = function()
|
||||
if not NetworkMgr:isOnline() then
|
||||
wifi_enabled_before_action = false
|
||||
NetworkMgr:beforeWifiAction(self.loadConfigAndProcessFeedsWithUI)
|
||||
else
|
||||
self:loadConfigAndProcessFeedsWithUI()
|
||||
end
|
||||
NetworkMgr:runWhenOnline(function() self:loadConfigAndProcessFeedsWithUI() end)
|
||||
end,
|
||||
},
|
||||
{
|
||||
@@ -222,7 +209,7 @@ function NewsDownloader:loadConfigAndProcessFeeds()
|
||||
end
|
||||
UI:info(T(_("Downloading news finished. Could not process some feeds. Unsupported format in: %1"), unsupported_urls))
|
||||
end
|
||||
NewsDownloader:afterWifiAction()
|
||||
NetworkMgr:afterWifiAction()
|
||||
end
|
||||
|
||||
function NewsDownloader:loadConfigAndProcessFeedsWithUI()
|
||||
|
||||
@@ -21,7 +21,6 @@ local Send2Ebook = WidgetContainer:new{
|
||||
}
|
||||
|
||||
local initialized = false
|
||||
local wifi_enabled_before_action = true
|
||||
local send2ebook_config_file = "send2ebook_settings.lua"
|
||||
local config_key_custom_dl_dir = "custom_dl_dir";
|
||||
local default_download_dir_name = "send2ebook"
|
||||
@@ -45,13 +44,6 @@ function Send2Ebook:downloadFileAndRemove(connection_url, remote_path, local_dow
|
||||
end
|
||||
end
|
||||
|
||||
--- @todo Implement as NetworkMgr:afterWifiAction with configuration options.
|
||||
function Send2Ebook:afterWifiAction()
|
||||
if not wifi_enabled_before_action then
|
||||
NetworkMgr:promptWifiOff()
|
||||
end
|
||||
end
|
||||
|
||||
function Send2Ebook:init()
|
||||
self.ui.menu:registerToMainMenu(self)
|
||||
end
|
||||
@@ -65,12 +57,10 @@ function Send2Ebook:addToMainMenu(menu_items)
|
||||
text = _("Download and remove from server"),
|
||||
keep_menu_open = true,
|
||||
callback = function()
|
||||
if not NetworkMgr:isOnline() then
|
||||
wifi_enabled_before_action = false
|
||||
NetworkMgr:beforeWifiAction(self.process)
|
||||
else
|
||||
self:process()
|
||||
end
|
||||
local connect_callback = function()
|
||||
self:process()
|
||||
end
|
||||
NetworkMgr:runWhenOnline(connect_callback)
|
||||
end,
|
||||
},
|
||||
{
|
||||
@@ -171,7 +161,7 @@ function Send2Ebook:process()
|
||||
end
|
||||
end
|
||||
UIManager:show(info)
|
||||
Send2Ebook:afterWifiAction()
|
||||
NetworkMgr:afterWifiAction()
|
||||
end
|
||||
|
||||
function Send2Ebook:removeReadActicles()
|
||||
|
||||
@@ -34,7 +34,7 @@ local function currentTime()
|
||||
return _("Time synchronized.")
|
||||
end
|
||||
|
||||
local function execute()
|
||||
local function syncNTP()
|
||||
local info = InfoMessage:new{
|
||||
text = _("Synchronizing time. This may take several seconds.")
|
||||
}
|
||||
@@ -58,11 +58,7 @@ local menuItem = {
|
||||
text = _("Synchronize time"),
|
||||
keep_menu_open = true,
|
||||
callback = function()
|
||||
if NetworkMgr:isOnline() then
|
||||
execute()
|
||||
else
|
||||
NetworkMgr:promptWifiOn()
|
||||
end
|
||||
NetworkMgr:runWhenOnline(function() syncNTP() end)
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
@@ -112,15 +112,14 @@ function Wallabag:addToMainMenu(menu_items)
|
||||
{
|
||||
text = _("Delete finished articles remotely"),
|
||||
callback = function()
|
||||
if not NetworkMgr:isOnline() then
|
||||
NetworkMgr:promptWifiOn()
|
||||
return
|
||||
local connect_callback = function()
|
||||
local num_deleted = self:processLocalFiles("manual")
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = T(_("Articles processed.\nDeleted: %1"), num_deleted)
|
||||
})
|
||||
self:refreshCurrentDirIfNeeded()
|
||||
end
|
||||
local num_deleted = self:processLocalFiles("manual")
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = T(_("Articles processed.\nDeleted: %1"), num_deleted)
|
||||
})
|
||||
self:refreshCurrentDirIfNeeded()
|
||||
NetworkMgr:runWhenOnline(connect_callback)
|
||||
end,
|
||||
enabled_func = function()
|
||||
return self.is_delete_finished or self.is_delete_read
|
||||
@@ -1078,12 +1077,11 @@ function Wallabag:onAddWallabagArticle(article_url)
|
||||
end
|
||||
|
||||
function Wallabag:onSynchronizeWallabag()
|
||||
if not NetworkMgr:isOnline() then
|
||||
NetworkMgr:promptWifiOn()
|
||||
return
|
||||
local connect_callback = function()
|
||||
self:synchronize()
|
||||
self:refreshCurrentDirIfNeeded()
|
||||
end
|
||||
self:synchronize()
|
||||
self:refreshCurrentDirIfNeeded()
|
||||
NetworkMgr:runWhenOnline(connect_callback)
|
||||
|
||||
-- stop propagation
|
||||
return true
|
||||
|
||||
@@ -41,15 +41,14 @@ function ZSync:addToMainMenu(menu_items)
|
||||
end,
|
||||
callback = function()
|
||||
local NetworkMgr = require("ui/network/manager")
|
||||
if not NetworkMgr:isOnline() then
|
||||
NetworkMgr:promptWifiOn()
|
||||
return
|
||||
end
|
||||
if not self.filemq_server then
|
||||
self:publish()
|
||||
else
|
||||
self:unpublish()
|
||||
local connect_callback = function()
|
||||
if not self.filemq_server then
|
||||
self:publish()
|
||||
else
|
||||
self:unpublish()
|
||||
end
|
||||
end
|
||||
NetworkMgr:runWhenOnline(connect_callback)
|
||||
end
|
||||
},
|
||||
{
|
||||
@@ -63,15 +62,14 @@ function ZSync:addToMainMenu(menu_items)
|
||||
end,
|
||||
callback = function()
|
||||
local NetworkMgr = require("ui/network/manager")
|
||||
if not NetworkMgr:isOnline() then
|
||||
NetworkMgr:promptWifiOn()
|
||||
return
|
||||
end
|
||||
if not self.filemq_client then
|
||||
self:subscribe()
|
||||
else
|
||||
self:unsubscribe()
|
||||
local connect_callback = function()
|
||||
if not self.filemq_client then
|
||||
self:subscribe()
|
||||
else
|
||||
self:unsubscribe()
|
||||
end
|
||||
end
|
||||
NetworkMgr:runWhenOnline(connect_callback)
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ describe("NetworkSetting module", function()
|
||||
assert.is.falsy(ns.connected_item)
|
||||
end)
|
||||
|
||||
it("should call connect_callback after disconnect", function()
|
||||
it("should NOT call connect_callback after disconnect", function()
|
||||
stub(NetworkMgr, "disconnectNetwork")
|
||||
stub(NetworkMgr, "releaseIP")
|
||||
|
||||
@@ -33,6 +33,33 @@ describe("NetworkSetting module", function()
|
||||
connect_callback = function() called = true end
|
||||
}
|
||||
ns.connected_item:disconnect()
|
||||
assert.falsy(called)
|
||||
|
||||
NetworkMgr.disconnectNetwork:revert()
|
||||
NetworkMgr.releaseIP:revert()
|
||||
end)
|
||||
|
||||
it("should call disconnect_callback after disconnect", function()
|
||||
stub(NetworkMgr, "disconnectNetwork")
|
||||
stub(NetworkMgr, "releaseIP")
|
||||
|
||||
UIManager:quit()
|
||||
local called = false
|
||||
local network_list = {
|
||||
{
|
||||
ssid = "foo",
|
||||
signal_level = -58,
|
||||
flags = "[WPA2-PSK-CCMP][ESS]",
|
||||
signal_quality = 84,
|
||||
password = "123abc",
|
||||
connected = true,
|
||||
},
|
||||
}
|
||||
local ns = NetworkSetting:new{
|
||||
network_list = network_list,
|
||||
disconnect_callback = function() called = true end
|
||||
}
|
||||
ns.connected_item:disconnect()
|
||||
assert.truthy(called)
|
||||
|
||||
NetworkMgr.disconnectNetwork:revert()
|
||||
|
||||
Reference in New Issue
Block a user