2
0
mirror of https://github.com/koreader/koreader synced 2024-11-16 06:12:56 +00:00
koreader/platform/pocketbook/koreader.app
ezdiy 893909146d
Pocketbook: use raw input I/O (#6791)
This allows for better energy efficiency (no more 50Hz tick poll),
as well as lower input lag / higher precision - touch events are
native linux ones.

In addition, auto off/suspend plugin is used in this mode, as we need
to trigger (timed) sleep / poweroff on our own, since the OS ones
will no longer work whenever koreader has focus.

This is for rooted devices only, and possibly somewhat FW
specific, so enabled only on PB740-2 where it's reasonably tested.
2020-10-17 12:59:24 +02:00

196 lines
7.9 KiB
Erlang
Executable File

#!/bin/sh
export LC_ALL="en_US.UTF-8"
# working directory of koreader
KOREADER_DIR="/mnt/ext1/applications/koreader"
# file through which we communicate instanced opens
export KO_PATH_OPEN_BOOK="/tmp/.koreader.open"
# check for and notify a running instance
INSTANCE_PID=$(cat /tmp/koreader.pid 2>/dev/null)
if [ "${INSTANCE_PID}" != "" ] && [ -e "/proc/${INSTANCE_PID}" ]; then
echo "$@" >"${KO_PATH_OPEN_BOOK}"
exec /usr/bin/iv2sh SetActiveTask "${INSTANCE_PID}" 0
fi
# try to bring in raw device input (on rooted devices)
/mnt/secure/su /bin/chmod 644 /dev/input/*
# we're first, so publish our instance
echo $$ >/tmp/koreader.pid
# update to new version from OTA directory
ko_update_check() {
NEWUPDATE="${KOREADER_DIR}/ota/koreader.updated.tar"
INSTALLED="${KOREADER_DIR}/ota/koreader.installed.tar"
if [ -f "${NEWUPDATE}" ]; then
"${KOREADER_DIR}/fbink" -q -y -7 -pmh "Updating KOReader"
# NOTE: See frontend/ui/otamanager.lua for a few more details on how we squeeze a percentage out of tar's checkpoint feature
# NOTE: %B should always be 512 in our case, so let stat do part of the maths for us instead of using %s ;).
FILESIZE="$(stat -c %b "${NEWUPDATE}")"
BLOCKS="$((FILESIZE / 20))"
export CPOINTS="$((BLOCKS / 100))"
# shellcheck disable=SC2016
cd /mnt/ext1 && "${KOREADER_DIR}/tar" xf "${NEWUPDATE}" --no-same-permissions --no-same-owner --checkpoint="${CPOINTS}" --checkpoint-action=exec='${KOREADER_DIR}/fbink -q -y -6 -P $(($TAR_CHECKPOINT/$CPOINTS))'
fail=$?
# Cleanup behind us...
if [ "${fail}" -eq 0 ]; then
mv "${NEWUPDATE}" "${INSTALLED}"
"${KOREADER_DIR}/fbink" -q -y -6 -pm "Update successful :)"
"${KOREADER_DIR}/fbink" -q -y -5 -pm "KOReader will start momentarily . . ."
else
# Uh oh...
"${KOREADER_DIR}/fbink" -q -y -6 -pmh "Update failed :("
"${KOREADER_DIR}/fbink" -q -y -5 -pm "KOReader may fail to function properly!"
fi
rm -f "${NEWUPDATE}" # always purge newupdate in all cases to prevent update loop
unset BLOCKS CPOINTS
# Ensure everything is flushed to disk before we restart. This *will* stall for a while on slow storage!
sync
# Don't forget to go back home, for proper restart behavior
cd ${KOREADER_DIR} || exit
fi
}
# we're always starting from our working directory
cd ${KOREADER_DIR} || exit
# export load library path for some old firmware
export LD_LIBRARY_PATH="${KOREADER_DIR}/libs:${LD_LIBRARY_PATH}"
# export trained OCR data directory
export TESSDATA_PREFIX="data"
# export dict directory
export STARDICT_DATA_DIR="data/dict"
# shellcheck disable=2000
if [ "$(echo "$@" | wc -c)" -eq 1 ]; then
args="/mnt/ext1/"
else
args="$*"
fi
# we keep at maximum 500K worth of crash log
if [ -e crash.log ]; then
tail -c 500000 crash.log >crash.log.new
mv -f crash.log.new crash.log
fi
export KO_EXIT_CODE="/tmp/.koreader.exit"
CRASH_COUNT=0
CRASH_TS=0
CRASH_PREV_TS=0
# List of supported special return codes
KO_RC_RESTART=85
#KO_RC_USBMS=86
# Ensure a clean slate on startup
rm -f "${KO_EXIT_CODE}"
RETURN_VALUE=${KO_RC_RESTART}
while [ "${RETURN_VALUE}" -ne 0 ]; do
if [ "${RETURN_VALUE}" -eq ${KO_RC_RESTART} ]; then
# Do an update check now, so we can actually update KOReader via the "Restart KOReader" menu entry ;).
ko_update_check
fi
./reader.lua "${args}" >>crash.log 2>&1
# Account for the fact a hard crash may have prevented the KO_EXIT_CODE file from being written to...
if [ -f "${KO_EXIT_CODE}" ]; then
RETURN_VALUE="$(cat ${KO_EXIT_CODE})"
rm -f "${KO_EXIT_CODE}"
else
# If we couldn't find it, something went horribly wrong ;).
RETURN_VALUE=42
fi
# Did we crash?
if [ "${RETURN_VALUE}" -ne 0 ] && [ "${RETURN_VALUE}" -ne ${KO_RC_RESTART} ]; then
# Increment the crash counter
CRASH_COUNT=$((CRASH_COUNT + 1))
CRASH_TS=$(date +'%s')
# Reset it to a first crash if it's been a while since our last crash...
if [ $((CRASH_TS - CRASH_PREV_TS)) -ge 20 ]; then
CRASH_COUNT=1
fi
# Check if the user requested to always abort on crash
if grep -q '\["dev_abort_on_crash"\] = true' 'settings.reader.lua' 2>/dev/null; then
ALWAYS_ABORT="true"
# In which case, make sure we pause on *every* crash
CRASH_COUNT=1
else
ALWAYS_ABORT="false"
fi
# Show a fancy bomb on screen
viewWidth=600
viewHeight=800
FONTH=16
eval "$("${KOREADER_DIR}/fbink" -e | tr ';' '\n' | grep -e viewWidth -e viewHeight -e FONTH | tr '\n' ';')"
# Compute margins & sizes relative to the screen's resolution, so we end up with a similar layout, no matter the device.
# Height @ ~56.7%, w/ a margin worth 1.5 lines
bombHeight=$((viewHeight / 2 + viewHeight / 15))
bombMargin=$((FONTH + FONTH / 2))
# With a little notice at the top of the screen, on a big gray screen of death ;).
"${KOREADER_DIR}/fbink" -q -b -c -B GRAY9 -m -y 1 "Don't Panic! (Crash n°${CRASH_COUNT} -> ${RETURN_VALUE})"
if [ ${CRASH_COUNT} -eq 1 ]; then
# Warn that we're sleeping for a bit...
"${KOREADER_DIR}/fbink" -q -b -O -m -y 2 "KOReader will restart in 15 sec."
fi
# U+1F4A3, the hard way, because we can't use \u or \U escape sequences...
# shellcheck disable=SC2039
"${KOREADER_DIR}/fbink" -q -b -O -m -t regular=${KOREADER_DIR}/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
"${KOREADER_DIR}/fbink" -q -b -O -t regular=${KOREADER_DIR}/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.
${KOREADER_DIR}/fbink -q -f -s
# Cue a lemming's faceplant sound effect!
{
echo "!!!!"
echo "Uh oh, something went awry... (Crash n°${CRASH_COUNT}: $(date +'%x @ %X'))"
} >>crash.log 2>&1
if [ ${CRASH_COUNT} -lt 5 ] && [ "${ALWAYS_ABORT}" = "false" ]; then
echo "Attempting to restart KOReader . . ." >>crash.log 2>&1
echo "!!!!" >>crash.log 2>&1
fi
# Pause a bit if it's the first crash in a while, so that it actually has a chance of getting noticed ;).
if [ ${CRASH_COUNT} -eq 1 ]; then
sleep 15
fi
# Cycle the last crash timestamp
CRASH_PREV_TS=${CRASH_TS}
# But if we've crashed more than 5 consecutive times, exit, because we wouldn't want to be stuck in a loop...
# NOTE: No need to check for ALWAYS_ABORT, CRASH_COUNT will always be 1 when it's true ;).
if [ ${CRASH_COUNT} -ge 5 ]; then
echo "Too many consecutive crashes, aborting . . ." >>crash.log 2>&1
echo "!!!! ! !!!!" >>crash.log 2>&1
break
fi
# If the user requested to always abort on crash, do so.
if [ "${ALWAYS_ABORT}" = "true" ]; then
echo "Aborting . . ." >>crash.log 2>&1
echo "!!!! ! !!!!" >>crash.log 2>&1
break
fi
else
# Reset the crash counter if that was a sane exit/restart
CRASH_COUNT=0
fi
done
rm -f "/tmp/koreader.pid"
if pidof reader.lua >/dev/null 2>&1; then
killall -TERM reader.lua
fi
exit "${RETURN_VALUE}"