From d303fdf6941c81769ee93215320222e7ca2df507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Fern=C3=A1ndez?= <975883+pazos@users.noreply.github.com> Date: Sat, 8 May 2021 23:02:35 +0200 Subject: [PATCH] android: Prompt for install updates when they're downloaded (#7632) --- base | 2 +- frontend/device/android/device.lua | 83 +++++++++++++++++++----------- frontend/device/generic/device.lua | 19 +++++++ frontend/ui/otamanager.lua | 39 ++++++-------- platform/android/llapp_main.lua | 2 +- platform/android/luajit-launcher | 2 +- 6 files changed, 89 insertions(+), 58 deletions(-) diff --git a/base b/base index 197f283e0..80bcdf5bc 160000 --- a/base +++ b/base @@ -1 +1 @@ -Subproject commit 197f283e0f3fc38b8b18a823457d70b251e66b97 +Subproject commit 80bcdf5bc7aa7f42135c08c31ed2ad99c358c181 diff --git a/frontend/device/android/device.lua b/frontend/device/android/device.lua index abf2cbe9f..1f64db202 100644 --- a/frontend/device/android/device.lua +++ b/frontend/device/android/device.lua @@ -13,16 +13,13 @@ local T = FFIUtil.template local function yes() return true end local function no() return false end -local function canUpdateApk() - -- disable updates on fdroid builds, since they manage their own repo. - return (android.prop.flavor ~= "fdroid") -end - local function getCodename() local api = android.app.activity.sdkVersion local codename = "" - if api > 29 then + if api > 30 then + codename = "S" + elseif api == 30 then codename = "R" elseif api == 29 then codename = "Q" @@ -87,7 +84,7 @@ local Device = Generic:new{ display_dpi = android.lib.AConfiguration_getDensity(android.app.config), isHapticFeedbackEnabled = yes, hasClipboard = yes, - hasOTAUpdates = canUpdateApk, + hasOTAUpdates = android.ota.isEnabled, hasFastWifiStatusQuery = yes, hasSystemFonts = yes, canOpenLink = yes, @@ -176,32 +173,37 @@ function Device:init() external.when_back_callback() external.when_back_callback = nil end - local new_file = android.getIntent() - if new_file ~= nil and lfs.attributes(new_file, "mode") == "file" then - -- we cannot blit to a window here since we have no focus yet. - local InfoMessage = require("ui/widget/infomessage") - local BD = require("ui/bidi") - UIManager:scheduleIn(0.1, function() - UIManager:show(InfoMessage:new{ - text = T(_("Opening file '%1'."), BD.filepath(new_file)), - timeout = 0.0, - }) - end) - UIManager:scheduleIn(0.2, function() - require("apps/reader/readerui"):doShowReader(new_file) - end) + + if android.ota.isPending then + UIManager:scheduleIn(0.1, self.install) else - -- check if we're resuming from importing content. - local content_path = android.getLastImportedPath() - if content_path ~= nil then - local FileManager = require("apps/filemanager/filemanager") - UIManager:scheduleIn(0.5, function() - if FileManager.instance then - FileManager.instance:onRefresh() - else - FileManager:showFiles(content_path) - end + local new_file = android.getIntent() + if new_file ~= nil and lfs.attributes(new_file, "mode") == "file" then + -- we cannot blit to a window here since we have no focus yet. + local InfoMessage = require("ui/widget/infomessage") + local BD = require("ui/bidi") + UIManager:scheduleIn(0.1, function() + UIManager:show(InfoMessage:new{ + text = T(_("Opening file '%1'."), BD.filepath(new_file)), + timeout = 0.0, + }) end) + UIManager:scheduleIn(0.2, function() + require("apps/reader/readerui"):doShowReader(new_file) + end) + else + -- check if we're resuming from importing content. + local content_path = android.getLastImportedPath() + if content_path ~= nil then + local FileManager = require("apps/filemanager/filemanager") + UIManager:scheduleIn(0.5, function() + if FileManager.instance then + FileManager.instance:onRefresh() + else + FileManager:showFiles(content_path) + end + end) + end end end elseif ev.code == C.APP_CMD_STOP then @@ -213,6 +215,12 @@ function Device:init() elseif ev.code == C.AEVENT_POWER_DISCONNECTED then local Event = require("ui/event") UIManager:broadcastEvent(Event:new("NotCharging")) + elseif ev.code == C.AEVENT_DOWNLOAD_COMPLETE then + if android.isResumed() then + self:install() + else + android.ota.isPending = true + end end end, hasClipboardText = function() @@ -451,6 +459,19 @@ function Device:untar(archive, extract_to) return android.untar(archive, extract_to) end +function Device:install() + local UIManager = require("ui/uimanager") + local ConfirmBox = require("ui/widget/confirmbox") + UIManager:show(ConfirmBox:new{ + text = _("Update is ready, Install it now?"), + ok_text = _("Install"), + ok_callback = function() + android.ota.install() + android.ota.isPending = false + end, + }) +end + -- todo: Wouldn't we like an android.deviceIdentifier() method, so we can use better default paths? function Device:getDefaultCoverPath() if android.prop.product == "ntx_6sl" then -- Tolino HD4 and other diff --git a/frontend/device/generic/device.lua b/frontend/device/generic/device.lua index 809c18be9..ca3121adc 100644 --- a/frontend/device/generic/device.lua +++ b/frontend/device/generic/device.lua @@ -340,6 +340,25 @@ function Device:info() return self.model end +function Device:install() + local Event = require("ui/event") + local UIManager = require("ui/uimanager") + local ConfirmBox = require("ui/widget/confirmbox") + UIManager:show(ConfirmBox:new{ + text = _("Update is ready. Install it now?"), + ok_text = _("Install"), + ok_callback = function() + local save_quit = function() + self:saveSettings() + UIManager:quit() + UIManager.exit_code = 85 + end + UIManager:broadcastEvent(Event:new("Exit", save_quit)) + end, + }) +end + + -- Hardware specific method to track opened/closed books (nil on book close) function Device:notifyBookState(title, document) end diff --git a/frontend/ui/otamanager.lua b/frontend/ui/otamanager.lua index 54d94c845..31d20f38b 100644 --- a/frontend/ui/otamanager.lua +++ b/frontend/ui/otamanager.lua @@ -6,7 +6,6 @@ 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 MultiConfirmBox = require("ui/widget/multiconfirmbox") local NetworkMgr = require("ui/network/manager") @@ -49,21 +48,6 @@ local ota_channels = { nightly = _("Development"), } -local function showRestartMessage() - UIManager:show(ConfirmBox:new{ - text = _("KOReader will be updated on next restart.\nWould you like to restart now?"), - ok_text = _("Restart"), - ok_callback = function() - local save_quit = function() - Device:saveSettings() - UIManager:quit() - UIManager._exit_code = 85 - end - UIManager:broadcastEvent(Event:new("Exit", save_quit)) - end, - }) -end - -- Try to detect WARIO+ Kindle boards (i.MX6 & i.MX7) function OTAManager:_isKindleWarioOrMore() local cpu_hw = nil @@ -247,6 +231,8 @@ function OTAManager:fetchAndProcessUpdate() update_ok_text = _("Downgrade") end + local wait_for_download = _("Downloading may take several minutes…") + if OTAManager:getOTAType() == "link" then UIManager:show(ConfirmBox:new{ text = update_message, @@ -254,13 +240,18 @@ function OTAManager:fetchAndProcessUpdate() ok_callback = function() local isAndroid, android = pcall(require, "android") if isAndroid then + local ffi = require("ffi") + local C = ffi.C -- try to download the package local ok = android.download(link, ota_package) - if ok == 1 then - android.notification(T(_("The file %1 already exists."), ota_package)) - elseif ok == 0 then - android.notification(T(_("Downloading %1"), ota_package)) - else + if ok == C.ADOWNLOAD_EXISTS then + Device:install() + elseif ok == C.ADOWNLOAD_OK then + UIManager:show(InfoMessage:new{ + text = wait_for_download, + timeout = 3, + }) + elseif ok == C.ADOWNLOAD_FAILED then UIManager:show(ConfirmBox:new{ text = _("Your device seems to be unable to download packages.\nRetry using the browser?"), ok_text = _("Retry"), @@ -278,12 +269,12 @@ function OTAManager:fetchAndProcessUpdate() ok_text = update_ok_text, ok_callback = function() UIManager:show(InfoMessage:new{ - text = _("Downloading may take several minutes…"), + text = wait_for_download, timeout = 3, }) UIManager:scheduleIn(1, function() if OTAManager:zsync() == 0 then - showRestartMessage() + Device:install() -- Make it clear that zsync is done if self.can_pretty_print then os.execute("./fbink -q -y -7 -pm ' ' ' '") @@ -309,7 +300,7 @@ function OTAManager:fetchAndProcessUpdate() -- And then relaunch zsync in full download mode... UIManager:scheduleIn(1, function() if OTAManager:zsync(true) == 0 then - showRestartMessage() + Device:install() -- Make it clear that zsync is done if self.can_pretty_print then os.execute("./fbink -q -y -7 -pm ' ' ' '") diff --git a/platform/android/llapp_main.lua b/platform/android/llapp_main.lua index 4d065dedf..709d5f264 100644 --- a/platform/android/llapp_main.lua +++ b/platform/android/llapp_main.lua @@ -38,7 +38,7 @@ local function runUserScripts(dir, migration, parent) end end -if android.prop.flavor ~= "fdroid" then +if android.prop.runtimeChanges then -- run scripts once after an update of koreader, -- it can also trigger a recursive migration of user data local run_once_scripts = path .. "/koreader/scripts.afterupdate" diff --git a/platform/android/luajit-launcher b/platform/android/luajit-launcher index a9ed9d219..290408a7f 160000 --- a/platform/android/luajit-launcher +++ b/platform/android/luajit-launcher @@ -1 +1 @@ -Subproject commit a9ed9d219dd8a10b99560813ef02b93465c5cb41 +Subproject commit 290408a7f1597232bcb743a33152ccc8728314ca