You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koreader/frontend/ui/widget/networksetting.lua

534 lines
16 KiB
Lua

--[[--
Network setting widget.
Example:
local network_list = {
{
ssid = "foo",
signal_level = -58,
flags = "[WPA2-PSK-CCMP][ESS]",
signal_quality = 84,
password = "123abc",
connected = true,
},
{
ssid = "bar",
signal_level = -258,
signal_quality = 44,
flags = "[WEP][ESS]",
},
}
UIManager:show(require("ui/widget/networksetting"):new{
network_list = network_list,
connect_callback = function()
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.
4 years ago
-- 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,
})
]]
local BD = require("ui/bidi")
local bit = require("bit")
local Blitbuffer = require("ffi/blitbuffer")
local CenterContainer = require("ui/widget/container/centercontainer")
local Device = require("device")
local Font = require("ui/font")
local Geom = require("ui/geometry")
local FrameContainer = require("ui/widget/container/framecontainer")
local GestureRange = require("ui/gesturerange")
local HorizontalGroup = require("ui/widget/horizontalgroup")
local HorizontalSpan = require("ui/widget/horizontalspan")
local IconWidget = require("ui/widget/iconwidget")
local InfoMessage = require("ui/widget/infomessage")
local InputContainer = require("ui/widget/container/inputcontainer")
local InputDialog = require("ui/widget/inputdialog")
local LeftContainer = require("ui/widget/container/leftcontainer")
local ListView = require("ui/widget/listview")
local RightContainer = require("ui/widget/container/rightcontainer")
local NetworkMgr = require("ui/network/manager")
local OverlapGroup = require("ui/widget/overlapgroup")
local Size = require("ui/size")
local TextWidget = require("ui/widget/textwidget")
local UIManager = require("ui/uimanager")
local util = require("util")
local VerticalGroup = require("ui/widget/verticalgroup")
local Widget = require("ui/widget/widget")
local _ = require("gettext")
local T = require("ffi/util").template
local Screen = Device.screen
local band = bit.band
local function obtainIP()
--- @todo check for DHCP result
local info = InfoMessage:new{text = _("Obtaining IP address…")}
UIManager:show(info)
UIManager:forceRePaint()
NetworkMgr:obtainIP()
UIManager:close(info)
end
Clarify our OOP semantics across the codebase (#9586) Basically: * Use `extend` for class definitions * Use `new` for object instantiations That includes some minor code cleanups along the way: * Updated `Widget`'s docs to make the semantics clearer. * Removed `should_restrict_JIT` (it's been dead code since https://github.com/koreader/android-luajit-launcher/pull/283) * Minor refactoring of LuaSettings/LuaData/LuaDefaults/DocSettings to behave (mostly, they are instantiated via `open` instead of `new`) like everything else and handle inheritance properly (i.e., DocSettings is now a proper LuaSettings subclass). * Default to `WidgetContainer` instead of `InputContainer` for stuff that doesn't actually setup key/gesture events. * Ditto for explicit `*Listener` only classes, make sure they're based on `EventListener` instead of something uselessly fancier. * Unless absolutely necessary, do not store references in class objects, ever; only values. Instead, always store references in instances, to avoid both sneaky inheritance issues, and sneaky GC pinning of stale references. * ReaderUI: Fix one such issue with its `active_widgets` array, with critical implications, as it essentially pinned *all* of ReaderUI's modules, including their reference to the `Document` instance (i.e., that was a big-ass leak). * Terminal: Make sure the shell is killed on plugin teardown. * InputText: Fix Home/End/Del physical keys to behave sensibly. * InputContainer/WidgetContainer: If necessary, compute self.dimen at paintTo time (previously, only InputContainers did, which might have had something to do with random widgets unconcerned about input using it as a baseclass instead of WidgetContainer...). * OverlapGroup: Compute self.dimen at *init* time, because for some reason it needs to do that, but do it directly in OverlapGroup instead of going through a weird WidgetContainer method that it was the sole user of. * ReaderCropping: Under no circumstances should a Document instance member (here, self.bbox) risk being `nil`ed! * Kobo: Minor code cleanups.
2 years ago
local MinimalPaginator = Widget:extend{
width = nil,
height = nil,
progress = nil,
}
function MinimalPaginator:getSize()
return Geom:new{w = self.width, h = self.height}
end
function MinimalPaginator:paintTo(bb, x, y)
self.dimen = self:getSize()
self.dimen.x, self.dimen.y = x, y
-- paint background
bb:paintRoundedRect(x, y,
self.dimen.w, self.dimen.h,
Blitbuffer.COLOR_LIGHT_GRAY)
-- paint percentage infill
bb:paintRect(x, y,
math.ceil(self.dimen.w*self.progress), self.dimen.h,
Blitbuffer.COLOR_DARK_GRAY)
end
function MinimalPaginator:setProgress(progress) self.progress = progress end
Clarify our OOP semantics across the codebase (#9586) Basically: * Use `extend` for class definitions * Use `new` for object instantiations That includes some minor code cleanups along the way: * Updated `Widget`'s docs to make the semantics clearer. * Removed `should_restrict_JIT` (it's been dead code since https://github.com/koreader/android-luajit-launcher/pull/283) * Minor refactoring of LuaSettings/LuaData/LuaDefaults/DocSettings to behave (mostly, they are instantiated via `open` instead of `new`) like everything else and handle inheritance properly (i.e., DocSettings is now a proper LuaSettings subclass). * Default to `WidgetContainer` instead of `InputContainer` for stuff that doesn't actually setup key/gesture events. * Ditto for explicit `*Listener` only classes, make sure they're based on `EventListener` instead of something uselessly fancier. * Unless absolutely necessary, do not store references in class objects, ever; only values. Instead, always store references in instances, to avoid both sneaky inheritance issues, and sneaky GC pinning of stale references. * ReaderUI: Fix one such issue with its `active_widgets` array, with critical implications, as it essentially pinned *all* of ReaderUI's modules, including their reference to the `Document` instance (i.e., that was a big-ass leak). * Terminal: Make sure the shell is killed on plugin teardown. * InputText: Fix Home/End/Del physical keys to behave sensibly. * InputContainer/WidgetContainer: If necessary, compute self.dimen at paintTo time (previously, only InputContainers did, which might have had something to do with random widgets unconcerned about input using it as a baseclass instead of WidgetContainer...). * OverlapGroup: Compute self.dimen at *init* time, because for some reason it needs to do that, but do it directly in OverlapGroup instead of going through a weird WidgetContainer method that it was the sole user of. * ReaderCropping: Under no circumstances should a Document instance member (here, self.bbox) risk being `nil`ed! * Kobo: Minor code cleanups.
2 years ago
local NetworkItem = InputContainer:extend{
dimen = nil,
height = Screen:scaleBySize(44),
icon_size = Screen:scaleBySize(32),
width = nil,
info = nil,
display_ssid = nil,
background = Blitbuffer.COLOR_WHITE,
}
function NetworkItem:init()
Clarify our OOP semantics across the codebase (#9586) Basically: * Use `extend` for class definitions * Use `new` for object instantiations That includes some minor code cleanups along the way: * Updated `Widget`'s docs to make the semantics clearer. * Removed `should_restrict_JIT` (it's been dead code since https://github.com/koreader/android-luajit-launcher/pull/283) * Minor refactoring of LuaSettings/LuaData/LuaDefaults/DocSettings to behave (mostly, they are instantiated via `open` instead of `new`) like everything else and handle inheritance properly (i.e., DocSettings is now a proper LuaSettings subclass). * Default to `WidgetContainer` instead of `InputContainer` for stuff that doesn't actually setup key/gesture events. * Ditto for explicit `*Listener` only classes, make sure they're based on `EventListener` instead of something uselessly fancier. * Unless absolutely necessary, do not store references in class objects, ever; only values. Instead, always store references in instances, to avoid both sneaky inheritance issues, and sneaky GC pinning of stale references. * ReaderUI: Fix one such issue with its `active_widgets` array, with critical implications, as it essentially pinned *all* of ReaderUI's modules, including their reference to the `Document` instance (i.e., that was a big-ass leak). * Terminal: Make sure the shell is killed on plugin teardown. * InputText: Fix Home/End/Del physical keys to behave sensibly. * InputContainer/WidgetContainer: If necessary, compute self.dimen at paintTo time (previously, only InputContainers did, which might have had something to do with random widgets unconcerned about input using it as a baseclass instead of WidgetContainer...). * OverlapGroup: Compute self.dimen at *init* time, because for some reason it needs to do that, but do it directly in OverlapGroup instead of going through a weird WidgetContainer method that it was the sole user of. * ReaderCropping: Under no circumstances should a Document instance member (here, self.bbox) risk being `nil`ed! * Kobo: Minor code cleanups.
2 years ago
self.dimen = Geom:new{x = 0, y = 0, w = self.width, h = self.height}
if not self.info.ssid then
self.info.ssid = "[hidden]"
end
self.display_ssid = util.fixUtf8(self.info.ssid, "<EFBFBD>")
local wifi_icon
if string.find(self.info.flags, "WPA") then
wifi_icon = "wifi.secure.%d"
else
wifi_icon = "wifi.open.%d"
end
-- Based on NetworkManager's nmc_wifi_strength_bars
-- c.f., https://github.com/NetworkManager/NetworkManager/blob/2fa8ef9fb9c7fe0cc2d9523eed6c5a3749b05175/clients/common/nm-client-utils.c#L585-L612
if self.info.signal_quality > 80 then
wifi_icon = string.format(wifi_icon, 100)
elseif self.info.signal_quality > 55 then
wifi_icon = string.format(wifi_icon, 75)
elseif self.info.signal_quality > 30 then
wifi_icon = string.format(wifi_icon, 50)
elseif self.info.signal_quality > 5 then
wifi_icon = string.format(wifi_icon, 25)
else
wifi_icon = string.format(wifi_icon, 0)
end
local horizontal_space = HorizontalSpan:new{width = Size.span.horizontal_default}
self.content_container = OverlapGroup:new{
dimen = self.dimen:copy(),
LeftContainer:new{
dimen = self.dimen:copy(),
HorizontalGroup:new{
horizontal_space,
IconWidget:new{
icon = wifi_icon,
width = self.icon_size,
height = self.icon_size,
},
horizontal_space,
TextWidget:new{
text = self.display_ssid,
face = Font:getFace("cfont"),
},
},
}
}
self.btn_disconnect = nil
self.btn_edit_nw = nil
if self.info.connected then
self.btn_disconnect = FrameContainer:new{
bordersize = 0,
padding = 0,
TextWidget:new{
text = _("disconnect"),
face = Font:getFace("cfont"),
}
}
table.insert(self.content_container, RightContainer:new{
dimen = self.dimen:copy(),
HorizontalGroup:new{
self.btn_disconnect,
horizontal_space,
}
})
self.setting_ui:setConnectedItem(self)
elseif self.info.password then
self.btn_edit_nw = FrameContainer:new{
bordersize = 0,
padding = 0,
TextWidget:new{
text = _("edit"),
face = Font:getFace("cfont"),
}
}
table.insert(self.content_container, RightContainer:new{
dimen = self.dimen:copy(),
HorizontalGroup:new{
self.btn_edit_nw,
horizontal_space,
}
})
end
self[1] = FrameContainer:new{
padding = 0,
margin = 0,
background = self.background,
bordersize = 0,
width = self.width,
self.content_container,
}
if Device:isTouchDevice() then
self.ges_events.TapSelect = {
GestureRange:new{
ges = "tap",
range = self.dimen,
}
}
end
end
function NetworkItem:refresh()
self:init()
UIManager:setDirty(self.setting_ui, function() return "ui", self.dimen end)
end
function NetworkItem:connect()
local connected_item = self.setting_ui:getConnectedItem()
if connected_item then connected_item:disconnect() end
local success, err_msg = NetworkMgr:authenticateNetwork(self.info)
local text
if success then
obtainIP()
self.info.connected = true
self.setting_ui:setConnectedItem(self)
text = _("Connected.")
else
text = err_msg
end
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.
4 years ago
-- Do what it says on the tin, and only trigger the connect_callback on a *successful* connect.
-- NOTE: This callback comes from NetworkManager, where it's named complete_callback.
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.
4 years ago
if success and self.setting_ui.connect_callback then
self.setting_ui.connect_callback()
end
self:refresh()
UIManager:show(InfoMessage:new{text = text, timeout = 3})
end
function NetworkItem:disconnect()
local info = InfoMessage:new{text = _("Disconnecting…")}
UIManager:show(info)
UIManager:forceRePaint()
NetworkMgr:disconnectNetwork(self.info)
NetworkMgr:releaseIP()
UIManager:close(info)
self.info.connected = nil
self:refresh()
self.setting_ui:setConnectedItem(nil)
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.
4 years ago
if self.setting_ui.disconnect_callback then
self.setting_ui.disconnect_callback()
end
end
function NetworkItem:saveAndConnectToNetwork(password_input)
local new_passwd = password_input:getInputText()
-- Dont set a empty password if WPA encryption, go through if its an open AP
3 years ago
if (new_passwd == nil or #new_passwd == 0) and string.find(self.info.flags, "WPA") then
UIManager:show(InfoMessage:new{
text = _("Password cannot be empty."),
})
else
if new_passwd ~= self.info.password then
self.info.password = new_passwd
self.info.psk = nil
NetworkMgr:saveNetwork(self.info)
end
self:connect()
end
UIManager:close(password_input)
end
function NetworkItem:onEditNetwork()
local password_input
password_input = InputDialog:new{
title = self.display_ssid,
input = self.info.password,
input_hint = _("password (leave empty for open networks)"),
input_type = "text",
text_type = "password",
buttons = {
{
{
text = _("Cancel"),
id = "close",
callback = function()
UIManager:close(password_input)
end,
},
{
text = _("Forget"),
callback = function()
NetworkMgr:deleteNetwork(self.info)
self.info.password = nil
-- remove edit button
table.remove(self.content_container, 2)
UIManager:close(password_input)
self:refresh()
end,
},
{
text = _("Connect"),
is_enter_default = true,
callback = function()
self:saveAndConnectToNetwork(password_input)
end,
},
},
},
}
UIManager:show(password_input)
password_input:onShowKeyboard()
return true
end
function NetworkItem:onAddNetwork()
local password_input
password_input = InputDialog:new{
title = self.display_ssid,
input = "",
input_hint = _("password (leave empty for open networks)"),
input_type = "text",
text_type = "password",
buttons = {
{
{
text = _("Cancel"),
id = "close",
callback = function()
UIManager:close(password_input)
end,
},
{
text = _("Connect"),
is_enter_default = true,
callback = function()
self:saveAndConnectToNetwork(password_input)
end,
},
},
},
}
UIManager:show(password_input)
password_input:onShowKeyboard()
return true
end
function NetworkItem:onTapSelect(arg, ges_ev)
-- Open AP dont have specific flag so we cant include them alongside WPA
-- so we exclude WEP instead (more encryption to exclude? not really future proof)
if string.find(self.info.flags, "WEP") then
UIManager:show(InfoMessage:new{
text = _("Networks with WEP encryption are not supported.")
})
return
end
if self.btn_disconnect then
-- noop if touch is not on disconnect button
if ges_ev.pos:intersectWith(self.btn_disconnect.dimen) then
self:disconnect()
end
elseif self.info.password then
if self.btn_edit_nw and ges_ev.pos:intersectWith(self.btn_edit_nw.dimen) then
self:onEditNetwork()
else
self:connect()
end
else
self:onAddNetwork()
end
return true
end
Clarify our OOP semantics across the codebase (#9586) Basically: * Use `extend` for class definitions * Use `new` for object instantiations That includes some minor code cleanups along the way: * Updated `Widget`'s docs to make the semantics clearer. * Removed `should_restrict_JIT` (it's been dead code since https://github.com/koreader/android-luajit-launcher/pull/283) * Minor refactoring of LuaSettings/LuaData/LuaDefaults/DocSettings to behave (mostly, they are instantiated via `open` instead of `new`) like everything else and handle inheritance properly (i.e., DocSettings is now a proper LuaSettings subclass). * Default to `WidgetContainer` instead of `InputContainer` for stuff that doesn't actually setup key/gesture events. * Ditto for explicit `*Listener` only classes, make sure they're based on `EventListener` instead of something uselessly fancier. * Unless absolutely necessary, do not store references in class objects, ever; only values. Instead, always store references in instances, to avoid both sneaky inheritance issues, and sneaky GC pinning of stale references. * ReaderUI: Fix one such issue with its `active_widgets` array, with critical implications, as it essentially pinned *all* of ReaderUI's modules, including their reference to the `Document` instance (i.e., that was a big-ass leak). * Terminal: Make sure the shell is killed on plugin teardown. * InputText: Fix Home/End/Del physical keys to behave sensibly. * InputContainer/WidgetContainer: If necessary, compute self.dimen at paintTo time (previously, only InputContainers did, which might have had something to do with random widgets unconcerned about input using it as a baseclass instead of WidgetContainer...). * OverlapGroup: Compute self.dimen at *init* time, because for some reason it needs to do that, but do it directly in OverlapGroup instead of going through a weird WidgetContainer method that it was the sole user of. * ReaderCropping: Under no circumstances should a Document instance member (here, self.bbox) risk being `nil`ed! * Kobo: Minor code cleanups.
2 years ago
local NetworkSetting = InputContainer:extend{
width = nil,
height = nil,
-- sample network_list entry: {
-- bssid = "any",
-- ssid = "foo",
-- signal_level = -58,
-- signal_quality = 84,
-- frequency = 5660,
-- flags = "[WPA2-PSK-CCMP][ESS]",
-- }
network_list = nil,
connect_callback = nil,
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.
4 years ago
disconnect_callback = nil,
}
function NetworkSetting:init()
self.width = self.width or Screen:getWidth() - Screen:scaleBySize(50)
self.width = math.min(self.width, Screen:scaleBySize(600))
local gray_bg = Blitbuffer.COLOR_GRAY_E
local items = {}
table.sort(self.network_list,
function(l, r) return l.signal_quality > r.signal_quality end)
for idx, network in ipairs(self.network_list) do
local bg
if band(idx, 1) == 0 then
bg = gray_bg
else
bg = Blitbuffer.COLOR_WHITE
end
table.insert(items, NetworkItem:new{
width = self.width,
info = network,
background = bg,
setting_ui = self,
})
end
self.status_text = TextWidget:new{
text = "",
face = Font:getFace("ffont"),
}
self.page_text = TextWidget:new{
text = "",
face = Font:getFace("ffont"),
}
self.pagination = MinimalPaginator:new{
width = self.width,
height = Screen:scaleBySize(8),
percentage = 0,
progress = 0,
}
self.height = self.height or math.min(Screen:getHeight()*3/4,
Screen:scaleBySize(800))
self.popup = FrameContainer:new{
background = Blitbuffer.COLOR_WHITE,
padding = 0,
bordersize = Size.border.window,
VerticalGroup:new{
align = "left",
self.pagination,
ListView:new{
padding = 0,
items = items,
width = self.width,
height = self.height-self.pagination:getSize().h,
page_update_cb = function(curr_page, total_pages)
self.pagination:setProgress(curr_page/total_pages)
-- self.page_text:setText(curr_page .. "/" .. total_pages)
UIManager:setDirty(self, function()
return "ui", self.popup.dimen
end)
end
},
},
}
self[1] = CenterContainer:new{
dimen = {w = Screen:getWidth(), h = Screen:getHeight()},
self.popup,
}
if Device:isTouchDevice() then
self.ges_events.TapClose = {
GestureRange:new{
ges = "tap",
range = Geom:new{
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight(),
}
}
}
end
Kindle: add wifi selector (#12056) * Kindle: Implement a NetworkMgr backend loosely based on WpaClient in order to allow feature-parity with hasWifiManager platforms. This involves dealing with the native wifid over lipc (the native IPC system, based on DBus), through custom Lua bindings (https://github.com/notmarek/openlipclua), since the stock ones lack support for the needed hasharray data type. * NetworkMgr: Clear up leftover hallucinations from #10669, making `enableWifi` much simpler (and much more similar to `turnOnWifiAndWaitForConnection`). * NetworkMgr: Made it clearer that `turnOnWifi` implementations *must* deal with `complete_callback`, as part of the aforementioned changes mean that it's *always* wrapped in a connectivity check, and we need that for proper event signaling. * Android, Emu: Run `complete_callback` properly in `turnOnWifi`. * Kindle: Support `powerd:isCharged()` on the PW2 (yes, this is random, it just happened to be my test device :D). * NetworkMgr:disableWifi: Properly tear down any potential ongoing connection attempt (e.g., connectivity check). * NetworkMgr:promptWifi: Make the "wifi enabled but not connected" popup clearer if there's an ongoing connection attempt, and gray out the "Connect" button in this case (as it would only lead to another "connection already in progress" popup anyway). * NetworkMgr:reconnectOrShowNetworkMenu: Make *total* scanning failures fatal (they will lead to an immediate wifi teardown). * NetworkMgr:reconnectOrShowNetworkMenu: Clear up the long-press behavior (which *always* shows the network list popup) so that it doesn't weirdly break all the things (technical term!). * NetworkMgr:reconnectOrShowNetworkMenu: When we manage to connect to a preferred network on our own *before* showing the network list, make sure it is flagged as "connected" in said list. * NetworkMgr:reconnectOrShowNetworkMenu: Make connection failures fatal in non-interactive workflows (they'll lead to a wifi teardown). * NetworkSetting (the aforementioned network list widget): Clear NetworkMgr's "connection pending" flag on dismiss when nothing else will (i.e., when there's no connectivity check ticking).
3 months ago
-- If the backend is already authenticated,
-- and NetworkMgr:reconnectOrShowNetworkMenu somehow missed it,
-- expedite the process.
-- Yes, this is a very old codepath that's hardly ever exercised anymore...
if not self.connect_callback then
return
end
UIManager:nextTick(function()
local connected_item = self:getConnectedItem()
if connected_item ~= nil then
obtainIP()
if G_reader_settings:nilOrTrue("auto_dismiss_wifi_scan") then
UIManager:close(self)
end
UIManager:show(InfoMessage:new{
text = T(_("Connected to network %1"), BD.wrap(connected_item.display_ssid)),
timeout = 3,
})
Kindle: add wifi selector (#12056) * Kindle: Implement a NetworkMgr backend loosely based on WpaClient in order to allow feature-parity with hasWifiManager platforms. This involves dealing with the native wifid over lipc (the native IPC system, based on DBus), through custom Lua bindings (https://github.com/notmarek/openlipclua), since the stock ones lack support for the needed hasharray data type. * NetworkMgr: Clear up leftover hallucinations from #10669, making `enableWifi` much simpler (and much more similar to `turnOnWifiAndWaitForConnection`). * NetworkMgr: Made it clearer that `turnOnWifi` implementations *must* deal with `complete_callback`, as part of the aforementioned changes mean that it's *always* wrapped in a connectivity check, and we need that for proper event signaling. * Android, Emu: Run `complete_callback` properly in `turnOnWifi`. * Kindle: Support `powerd:isCharged()` on the PW2 (yes, this is random, it just happened to be my test device :D). * NetworkMgr:disableWifi: Properly tear down any potential ongoing connection attempt (e.g., connectivity check). * NetworkMgr:promptWifi: Make the "wifi enabled but not connected" popup clearer if there's an ongoing connection attempt, and gray out the "Connect" button in this case (as it would only lead to another "connection already in progress" popup anyway). * NetworkMgr:reconnectOrShowNetworkMenu: Make *total* scanning failures fatal (they will lead to an immediate wifi teardown). * NetworkMgr:reconnectOrShowNetworkMenu: Clear up the long-press behavior (which *always* shows the network list popup) so that it doesn't weirdly break all the things (technical term!). * NetworkMgr:reconnectOrShowNetworkMenu: When we manage to connect to a preferred network on our own *before* showing the network list, make sure it is flagged as "connected" in said list. * NetworkMgr:reconnectOrShowNetworkMenu: Make connection failures fatal in non-interactive workflows (they'll lead to a wifi teardown). * NetworkSetting (the aforementioned network list widget): Clear NetworkMgr's "connection pending" flag on dismiss when nothing else will (i.e., when there's no connectivity check ticking).
3 months ago
self.connect_callback()
end
end)
end
function NetworkSetting:setConnectedItem(item)
self.connected_item = item
end
function NetworkSetting:getConnectedItem()
return self.connected_item
end
function NetworkSetting:onTapClose(arg, ges_ev)
if ges_ev.pos:notIntersectWith(self.popup.dimen) then
UIManager:close(self)
return true
end
end
Kindle: add wifi selector (#12056) * Kindle: Implement a NetworkMgr backend loosely based on WpaClient in order to allow feature-parity with hasWifiManager platforms. This involves dealing with the native wifid over lipc (the native IPC system, based on DBus), through custom Lua bindings (https://github.com/notmarek/openlipclua), since the stock ones lack support for the needed hasharray data type. * NetworkMgr: Clear up leftover hallucinations from #10669, making `enableWifi` much simpler (and much more similar to `turnOnWifiAndWaitForConnection`). * NetworkMgr: Made it clearer that `turnOnWifi` implementations *must* deal with `complete_callback`, as part of the aforementioned changes mean that it's *always* wrapped in a connectivity check, and we need that for proper event signaling. * Android, Emu: Run `complete_callback` properly in `turnOnWifi`. * Kindle: Support `powerd:isCharged()` on the PW2 (yes, this is random, it just happened to be my test device :D). * NetworkMgr:disableWifi: Properly tear down any potential ongoing connection attempt (e.g., connectivity check). * NetworkMgr:promptWifi: Make the "wifi enabled but not connected" popup clearer if there's an ongoing connection attempt, and gray out the "Connect" button in this case (as it would only lead to another "connection already in progress" popup anyway). * NetworkMgr:reconnectOrShowNetworkMenu: Make *total* scanning failures fatal (they will lead to an immediate wifi teardown). * NetworkMgr:reconnectOrShowNetworkMenu: Clear up the long-press behavior (which *always* shows the network list popup) so that it doesn't weirdly break all the things (technical term!). * NetworkMgr:reconnectOrShowNetworkMenu: When we manage to connect to a preferred network on our own *before* showing the network list, make sure it is flagged as "connected" in said list. * NetworkMgr:reconnectOrShowNetworkMenu: Make connection failures fatal in non-interactive workflows (they'll lead to a wifi teardown). * NetworkSetting (the aforementioned network list widget): Clear NetworkMgr's "connection pending" flag on dismiss when nothing else will (i.e., when there's no connectivity check ticking).
3 months ago
function NetworkSetting:onCloseWidget()
-- If we don't have a connectivity check ticking, assume we're done with this connection attempt *now*
if not NetworkMgr.pending_connectivity_check then
NetworkMgr.pending_connection = false
end
UIManager:setDirty(nil, "ui", self.popup.dimen)
Kindle: add wifi selector (#12056) * Kindle: Implement a NetworkMgr backend loosely based on WpaClient in order to allow feature-parity with hasWifiManager platforms. This involves dealing with the native wifid over lipc (the native IPC system, based on DBus), through custom Lua bindings (https://github.com/notmarek/openlipclua), since the stock ones lack support for the needed hasharray data type. * NetworkMgr: Clear up leftover hallucinations from #10669, making `enableWifi` much simpler (and much more similar to `turnOnWifiAndWaitForConnection`). * NetworkMgr: Made it clearer that `turnOnWifi` implementations *must* deal with `complete_callback`, as part of the aforementioned changes mean that it's *always* wrapped in a connectivity check, and we need that for proper event signaling. * Android, Emu: Run `complete_callback` properly in `turnOnWifi`. * Kindle: Support `powerd:isCharged()` on the PW2 (yes, this is random, it just happened to be my test device :D). * NetworkMgr:disableWifi: Properly tear down any potential ongoing connection attempt (e.g., connectivity check). * NetworkMgr:promptWifi: Make the "wifi enabled but not connected" popup clearer if there's an ongoing connection attempt, and gray out the "Connect" button in this case (as it would only lead to another "connection already in progress" popup anyway). * NetworkMgr:reconnectOrShowNetworkMenu: Make *total* scanning failures fatal (they will lead to an immediate wifi teardown). * NetworkMgr:reconnectOrShowNetworkMenu: Clear up the long-press behavior (which *always* shows the network list popup) so that it doesn't weirdly break all the things (technical term!). * NetworkMgr:reconnectOrShowNetworkMenu: When we manage to connect to a preferred network on our own *before* showing the network list, make sure it is flagged as "connected" in said list. * NetworkMgr:reconnectOrShowNetworkMenu: Make connection failures fatal in non-interactive workflows (they'll lead to a wifi teardown). * NetworkSetting (the aforementioned network list widget): Clear NetworkMgr's "connection pending" flag on dismiss when nothing else will (i.e., when there's no connectivity check ticking).
3 months ago
end
return NetworkSetting