diff --git a/frontend/device/cervantes/device.lua b/frontend/device/cervantes/device.lua index a867f9501..5e72768ac 100644 --- a/frontend/device/cervantes/device.lua +++ b/frontend/device/cervantes/device.lua @@ -21,6 +21,14 @@ local function isConnected() return carrier end +local function isMassStorageSupported() + -- we rely on 3rd party package for that. It should be installed as part of KOReader prerequisites, + local safemode_version = io.open("/usr/share/safemode/version", "rb") + if not safemode_version then return false end + safemode_version:close() + return true +end + local Cervantes = Generic:new{ model = "Cervantes", isCervantes = yes, @@ -33,6 +41,9 @@ local Cervantes = Generic:new{ hasOTAUpdates = yes, hasKeys = yes, + -- do we support usb mass storage? + canToggleMassStorage = function() return isMassStorageSupported() end, + -- all devices, except the original Cervantes Touch, have frontlight hasFrontlight = yes, diff --git a/frontend/device/generic/device.lua b/frontend/device/generic/device.lua index 28b5ef695..8639586de 100644 --- a/frontend/device/generic/device.lua +++ b/frontend/device/generic/device.lua @@ -30,6 +30,7 @@ local Device = { hasColorScreen = no, hasBGRFrameBuffer = no, canToggleGSensor = no, + canToggleMassStorage = no, -- use these only as a last resort. We should abstract the functionality -- and have device dependent implementations in the corresponting diff --git a/frontend/ui/elements/common_settings_menu_table.lua b/frontend/ui/elements/common_settings_menu_table.lua index 218113c87..05f2e7a05 100644 --- a/frontend/ui/elements/common_settings_menu_table.lua +++ b/frontend/ui/elements/common_settings_menu_table.lua @@ -21,6 +21,22 @@ if Device:hasFrontlight() then } end +if Device:canToggleMassStorage() then + local MassStorage = require("ui/elements/mass_storage") + + -- mass storage settings + common_settings.mass_storage_settings = { + text = _("USB mass storage"), + sub_item_table = MassStorage:getSettingsMenuTable() + } + + -- mass storage actions + common_settings.mass_storage_actions = { + text = _("Start USB storage"), + callback = function() MassStorage:start() end, + } +end + if Device:setDateTime() then common_settings.time = { text = _("Time and date"), diff --git a/frontend/ui/elements/filemanager_menu_order.lua b/frontend/ui/elements/filemanager_menu_order.lua index 7817663b5..e1278649a 100644 --- a/frontend/ui/elements/filemanager_menu_order.lua +++ b/frontend/ui/elements/filemanager_menu_order.lua @@ -39,6 +39,7 @@ local order = { "time", "battery", "gesture", + "mass_storage_settings", }, network = { "network_wifi", @@ -95,6 +96,7 @@ local order = { "open_last_document", "----------------------------", "system_statistics", + "mass_storage_actions", "----------------------------", "ota_update", -- if Device:hasOTAUpdates() "version", diff --git a/frontend/ui/elements/mass_storage.lua b/frontend/ui/elements/mass_storage.lua new file mode 100644 index 000000000..6665c2e17 --- /dev/null +++ b/frontend/ui/elements/mass_storage.lua @@ -0,0 +1,54 @@ +local UIManager = require("ui/uimanager") +local _ = require("gettext") + +local MassStorage = {} + +-- if required a popup will ask before entering mass storage mode +function MassStorage:requireConfirmation() + return not G_reader_settings:isTrue("mass_storage_confirmation_disabled") +end + +-- mass storage settings menu +function MassStorage:getSettingsMenuTable() + return { + { + text = _("Disable confirmation popup"), + checked_func = function() return not self:requireConfirmation() end, + callback = function() + G_reader_settings:saveSetting("mass_storage_confirmation_disabled", self:requireConfirmation()) + end, + }, + } +end + +-- mass storage actions +function MassStorage:getActionsMenuTable() + return { + { + text = _("Start USB storage"), + callback = function() + self:start() + end, + }, + } +end + +-- exit KOReader and start mass storage mode. +function MassStorage:start() + if self:requireConfirmation() then + local ConfirmBox = require("ui/widget/confirmbox") + UIManager:show(ConfirmBox:new{ + text = _("Share storage via USB?\n"), + ok_text = _("Share"), + ok_callback = function() + UIManager:quit() + UIManager._exit_code = 86 + end, + }) + else + UIManager:quit() + UIManager._exit_code = 86 + end +end + +return MassStorage diff --git a/frontend/ui/elements/reader_menu_order.lua b/frontend/ui/elements/reader_menu_order.lua index c380e993f..4695d6983 100644 --- a/frontend/ui/elements/reader_menu_order.lua +++ b/frontend/ui/elements/reader_menu_order.lua @@ -61,6 +61,7 @@ local order = { "time", "battery", "gesture", + "mass_storage_settings", }, network = { "network_wifi", @@ -119,6 +120,7 @@ local order = { "book_info", "----------------------------", "system_statistics", + "mass_storage_actions", "----------------------------", "ota_update", -- if Device:hasOTAUpdates() "version", diff --git a/platform/cervantes/koreader.sh b/platform/cervantes/koreader.sh index 91970aa16..289897919 100755 --- a/platform/cervantes/koreader.sh +++ b/platform/cervantes/koreader.sh @@ -82,10 +82,25 @@ if [ "${STANDALONE}" != "true" ]; then [ -x /etc/init.d/connman ] && /etc/init.d/connman stop fi -RETURN_VALUE=85 -while [ "${RETURN_VALUE}" -eq 85 ]; do +# **magic** values to request shell stuff. It starts at 85, +# any number lower than that will exit this script. +RESTART_KOREADER=85 +ENTER_USBMS=86 +RETURN_VALUE="${RESTART_KOREADER}" + +# Loop forever until KOReader requests a normal exit. +while [ "${RETURN_VALUE}" -ge "${RESTART_KOREADER}" ]; do ./reader.lua "${args}" >>crash.log 2>&1 RETURN_VALUE=$? + + # check if KOReader requested to enter in mass storage mode. + if [ "${RETURN_VALUE}" -eq "${ENTER_USBMS}" ]; then + # NOTE: at this point we're sure that the safemode tool + # is recent enough to support the "--force" flag. + + safemode storage --force 2>/dev/null + # waiting forever for home button events. + fi done if [ "${STANDALONE}" != "true" ]; then