D configs/default_hooks/can_suspend => configs/default_hooks/can_suspend +0 -54
@@ 1,54 0,0 @@
-#!/bin/sh
-# configversion: 1
-
-# This hook goal is to return a non zero exit code if the device
-# should wait before going to suspension
-
-. "$(which sxmo_common.sh)"
-
-exit_should_wait() {
- sxmo_log "$*"
- printf %s "$1"
- exit 1
-}
-
-modem_use() {
- (pgrep -f sxmo_modem.sh > /dev/null || \
- pgrep -f sxmo_mms.sh > /dev/null || \
- pgrep -f mmcli > /dev/null || \
- pgrep -f mmsctl > /dev/null || \
- pgrep -f sxmo_modemsendsms.sh > /dev/null || \
- sxmo_daemons.sh running modem_nocrust || \
- pgrep -f sxmo_modemdaemons.sh >/dev/null) && exit_should_wait "modem"
-}
-
-active_ssh() {
- (netstat | grep ESTABLISHED | grep -q ssh) && exit_should_wait "ssh"
-}
-
-screenlock() {
- pgrep -f sxmo_screenlock.sh >/dev/null && exit_should_wait "screenlock"
-}
-
-playing_mpc() {
- command -v mpc > /dev/null || return # no mpc installed
-
- (mpc status | grep -q '\[playing\]') && exit_should_wait "mpc"
-}
-
-photos_processing() {
- pgrep -f postprocess.sh > /dev/null && exit_should_wait "photos processing"
-}
-
-auto_suspend() {
- [ -e "$XDG_CACHE_HOME/sxmo/sxmo.nosuspend" ] && exit_should_wait "auto_suspend_off"
-}
-
-modem_use
-playing_mpc
-screenlock
-photos_processing
-auto_suspend
-active_ssh
-
-exit 0
A configs/default_hooks/check_state_mutexes => configs/default_hooks/check_state_mutexes +106 -0
@@ 0,0 1,106 @@
+#!/bin/sh
+
+# This hook goal is to setup mutexes if the device must be considered
+# as idle or not, if it can go to crust or not
+
+. "$(which sxmo_common.sh)"
+
+lock_suspend_mutex() {
+ if ! MUTEX_NAME=can_suspend sxmo_mutex.sh lockedby "$1"; then
+ MUTEX_NAME=can_suspend sxmo_mutex.sh lock "$1"
+ fi
+}
+
+free_suspend_mutex() {
+ MUTEX_NAME=can_suspend sxmo_mutex.sh free "$1"
+}
+
+lock_idle_mutex() {
+ if ! MUTEX_NAME=is_idle sxmo_mutex.sh lockedby "$1"; then
+ MUTEX_NAME=is_idle sxmo_mutex.sh lock "$1"
+ fi
+
+ lock_suspend_mutex "$1" # not idle also mean not suspending
+}
+
+free_idle_mutex() {
+ MUTEX_NAME=is_idle sxmo_mutex.sh free "$1"
+
+ free_suspend_mutex "$1"
+}
+
+PIDS=""
+
+# ongoing_call
+if pgrep -f sxmo_modemcall.sh > /dev/null; then
+ lock_idle_mutex "Ongoing call"
+else
+ free_idle_mutex "Ongoing call"
+fi &
+PIDS="$PIDS $!"
+
+# camera_open
+if pgrep -f megapixels > /dev/null; then
+ lock_idle_mutex "Megapixels is open"
+else
+ free_idle_mutex "Megapixels is open"
+fi &
+PIDS="$PIDS $!"
+
+# auto_screenoff
+if [ -e "$XDG_CACHE_HOME/sxmo/sxmo.noidle" ]; then
+ lock_idle_mutex "Manually disabled"
+else
+ free_idle_mutex "Manually disabled"
+fi &
+PIDS="$PIDS $!"
+
+# modem_use
+if pgrep -f sxmo_modem.sh > /dev/null || \
+ pgrep -f sxmo_mms.sh > /dev/null || \
+ pgrep -f mmcli > /dev/null || \
+ pgrep -f mmsctl > /dev/null || \
+ pgrep -f sxmo_modemsendsms.sh > /dev/null || \
+ sxmo_daemons.sh running modem_nocrust -q || \
+ pgrep -f sxmo_modemdaemons.sh >/dev/null; then
+ lock_suspend_mutex "Modem is used"
+else
+ free_suspend_mutex "Modem is used"
+fi &
+PIDS="$PIDS $!"
+
+# active_ssh
+if netstat | grep ESTABLISHED | grep -q ssh; then
+ lock_suspend_mutex "SSH is connected"
+else
+ free_suspend_mutex "SSH is connected"
+fi &
+PIDS="$PIDS $!"
+
+# playing_mpc
+if command -v mpc > /dev/null && mpc status | grep -q '\[playing\]'; then
+ lock_suspend_mutex "MPD is playing music"
+else
+ free_suspend_mutex "MPD is playing music"
+fi &
+PIDS="$PIDS $!"
+
+# photos_processing
+if pgrep -f postprocess.sh > /dev/null; then
+ lock_suspend_mutex "Camera postprocessing"
+else
+ free_suspend_mutex "Camera postprocessing"
+fi &
+PIDS="$PIDS $!"
+
+# auto_suspend
+if [ -e "$XDG_CACHE_HOME/sxmo/sxmo.nosuspend" ]; then
+ lock_suspend_mutex "Manually disabled"
+else
+ free_suspend_mutex "Manually disabled"
+fi &
+PIDS="$PIDS $!"
+
+for PID in $PIDS; do
+ wait "$PID"
+done
D configs/default_hooks/is_idle => configs/default_hooks/is_idle +0 -47
@@ 1,47 0,0 @@
-#!/bin/sh
-# configversion: 1
-
-# include common definitions
-# shellcheck source=scripts/core/sxmo_common.sh
-. "$(which sxmo_common.sh)"
-
-# This hook goal is to return a non zero exit code if the device
-# must be considered not idle (ongoing call, playing mpd, etc)
-
-exit_not_idle() {
- sxmo_log "$*"
- printf %s "$1"
- exit 1
-}
-
-
-ongoing_call() {
- pgrep -f sxmo_modemcall.sh > /dev/null && exit_not_idle "call"
-}
-
-proximity_lock_on() {
- sxmo_daemons.sh running proximity_lock -q && exit_not_idle "proxlock"
-}
-
-camera_open() {
- pgrep -f megapixels > /dev/null && exit_not_idle "camera"
-}
-
-waiting_rtcwake() {
- if grep -q crust "$SXMO_LASTSTATE" && \
- grep -q rtc "$SXMO_UNSUSPENDREASONFILE"; then
- exit_not_idle "rtcwake"
- fi
-}
-
-auto_screenoff() {
- [ -e "$XDG_CACHE_HOME/sxmo/sxmo.noidle" ] && exit_not_idle "auto_screenoff_off"
-}
-
-ongoing_call
-proximity_lock_on
-waiting_rtcwake
-camera_open
-auto_screenoff
-
-exit 0
M configs/default_hooks/lock => configs/default_hooks/lock +4 -2
@@ 23,7 23,9 @@ wait "$LEDPID"
# Start a periodic daemon (8s) "try to go to off" after 8 seconds
# Resume tasks stop daemons
sxmo_daemons.sh start idle_locker sxmo_idle.sh -w \
- timeout 8 'sxmo_daemons.sh start periodic_deeper sxmo_run_periodically.sh 8 sxmo_screenlock_deeper.sh --idle' \
- resume 'sxmo_daemons.sh stop periodic_deeper'
+ timeout 8 'MUTEX_NAME=is_idle sxmo_daemons.sh start going_deeper sh -c "sxmo_hooks.sh check_state_mutexes && exec sxmo_mutex.sh holdexec sxmo_screenlock.sh off"' \
+ resume 'sxmo_daemons.sh stop going_deeper' \
+ timeout 12 'sxmo_daemons.sh start periodic_state_mutex_check sxmo_run_periodically.sh 10 sxmo_hooks.sh check_state_mutexes' \
+ resume 'sxmo_daemons.sh stop periodic_state_mutex_check'
sxmo_daemons.sh signal desktop_widget -12
M configs/default_hooks/presuspend => configs/default_hooks/presuspend +2 -0
@@ 6,6 6,8 @@
# shellcheck source=scripts/core/sxmo_common.sh
. "$(which sxmo_common.sh)"
+sxmo_daemons.sh stop periodic_blink
+
pkill clickclack
sxmo_keyboard.sh close
pkill mpv #if any audio/video is playing, kill it (it might stutter otherwise)
M configs/default_hooks/screenoff => configs/default_hooks/screenoff +9 -5
@@ 33,12 33,16 @@ esac
# Resume tasks stop daemons
if [ -z "$SXMO_DISABLE_LEDS" ]; then
sxmo_daemons.sh start idle_locker sxmo_idle.sh -w \
- timeout 8 'sxmo_daemons.sh start periodic_deeper sxmo_run_periodically.sh 8 sxmo_screenlock_deeper.sh --idle' \
- resume 'sxmo_daemons.sh stop periodic_deeper' \
+ timeout 8 'MUTEX_NAME=can_suspend sxmo_daemons.sh start going_deeper sh -c "sxmo_hooks.sh check_state_mutexes && exec sxmo_mutex.sh holdexec sxmo_screenlock.sh crust"' \
+ resume 'sxmo_daemons.sh stop going_deeper' \
timeout 5 'sxmo_daemons.sh start periodic_blink sxmo_run_periodically.sh 2 sxmo_led.sh blink red blue' \
- resume 'sxmo_daemons.sh stop periodic_blink'
+ resume 'sxmo_daemons.sh stop periodic_blink' \
+ timeout 12 'sxmo_daemons.sh start periodic_state_mutex_check sxmo_run_periodically.sh 10 sxmo_hooks.sh check_state_mutexes' \
+ resume 'sxmo_daemons.sh stop periodic_state_mutex_check'
else
sxmo_daemons.sh start idle_locker sxmo_idle.sh -w \
- timeout 8 'sxmo_daemons.sh start periodic_deeper sxmo_run_periodically.sh 8 sxmo_screenlock_deeper.sh --idle' \
- resume 'sxmo_daemons.sh stop periodic_deeper'
+ timeout 8 'MUTEX_NAME=can_suspend sxmo_daemons.sh start going_deeper sh -c "sxmo_hooks.sh check_state_mutexes && exec sxmo_mutex.sh holdexec sxmo_screenlock.sh crust"' \
+ resume 'sxmo_daemons.sh stop going_deeper' \
+ timeout 12 'sxmo_daemons.sh start periodic_state_mutex_check sxmo_run_periodically.sh 10 sxmo_hooks.sh check_state_mutexes' \
+ resume 'sxmo_daemons.sh stop periodic_state_mutex_check'
fi
M configs/default_hooks/unlock => configs/default_hooks/unlock +4 -2
@@ 28,7 28,9 @@ echo 16000 > "$NETWORKRTCSCAN"
# Start a periodic daemon (10s) "try to go to lock" after 120 seconds
# Resume tasks stop daemons
sxmo_daemons.sh start idle_locker sxmo_idle.sh -w \
- timeout "${SXMO_UNLOCK_IDLE_TIME:-120}" 'sxmo_daemons.sh start periodic_deeper sxmo_run_periodically.sh 10 sxmo_screenlock_deeper.sh --idle' \
- resume 'sxmo_daemons.sh stop periodic_deeper'
+ timeout "${SXMO_UNLOCK_IDLE_TIME:-120}" 'MUTEX_NAME=is_idle sxmo_daemons.sh start going_deeper sh -c "sxmo_hooks.sh check_state_mutexes && exec sxmo_mutex.sh holdexec sxmo_screenlock.sh lock"' \
+ resume 'sxmo_daemons.sh stop going_deeper' \
+ timeout "$((${SXMO_UNLOCK_IDLE_TIME:-120} + 10))" 'sxmo_daemons.sh start periodic_state_mutex_check sxmo_run_periodically.sh 10 sxmo_hooks.sh check_state_mutexes' \
+ resume 'sxmo_daemons.sh stop periodic_state_mutex_check'
sxmo_daemons.sh signal desktop_widget -12
M scripts/core/sxmo_led.sh => scripts/core/sxmo_led.sh +6 -3
@@ 3,10 3,13 @@
. "$(which sxmo_common.sh)"
free_mutex() {
+ MUTEX_NAME=can_suspend sxmo_mutex.sh free "Playing with leds"
rmdir "$XDG_RUNTIME_DIR"/sxmo.led.lock
}
-check_mutex() {
+ensure_mutex() {
+ MUTEX_NAME=can_suspend sxmo_mutex.sh lock "Playing with leds"
+
while ! mkdir "$XDG_RUNTIME_DIR"/sxmo.led.lock 2> /dev/null; do
sleep 0.1
done
@@ 118,11 121,11 @@ cmd="$1"
shift
case "$cmd" in
"set")
- check_mutex
+ ensure_mutex
set_leds "$@"
;;
get|blink)
- check_mutex
+ ensure_mutex
"$cmd"_led "$@"
;;
A scripts/core/sxmo_mutex.sh => scripts/core/sxmo_mutex.sh +71 -0
@@ 0,0 1,71 @@
+#!/bin/sh
+
+set -e
+
+MUTEX_NAME="${MUTEX_NAME:-default}"
+ROOT_DIR="${XDG_RUNTIME_DIR:-$HOME/.local/run}/sxmo_mutex"
+REASON_FILE="$ROOT_DIR/$MUTEX_NAME"
+mkdir -p "$(dirname "$REASON_FILE")"
+touch "$REASON_FILE"
+
+lock() {
+ printf "%s\n" "$1" >> "$REASON_FILE"
+}
+
+free() {
+ grep -xnm1 "$1" "$REASON_FILE" | \
+ cut -d: -f1 | \
+ xargs -rn1 -I{} sed -i '{}d' "$REASON_FILE"
+}
+
+lockedby() {
+ grep -qxm1 "$1" "$REASON_FILE"
+}
+
+freeall() {
+ printf "" > "$REASON_FILE"
+}
+
+list() {
+ cat "$REASON_FILE"
+}
+
+hold() {
+ if ! [ -s "$REASON_FILE" ]; then
+ exit 0
+ fi
+
+ FIFO="$(mktemp -u)"
+ mkfifo "$FIFO"
+ inotifywait -mq -e "close_write" "$ROOT_DIR" >> "$FIFO" &
+ NOTIFYPID=$!
+
+ finish() {
+ kill "$NOTIFYPID"
+ rm "$FIFO"
+ exit 0
+ }
+ trap 'finish' TERM INT EXIT
+
+ while read -r; do
+ if ! [ -s "$REASON_FILE" ]; then
+ exit 0
+ fi
+ done < "$FIFO"
+}
+
+holdexec() {
+ finish() {
+ kill "$HOLDPID"
+ exit
+ }
+ trap 'finish' TERM INT
+
+ hold &
+ HOLDPID=$!
+ wait "$HOLDPID"
+
+ "$@"
+}
+
+"$@"
M scripts/core/sxmo_proximitylock.sh => scripts/core/sxmo_proximitylock.sh +3 -1
@@ 6,14 6,16 @@ isLocked() {
}
finish() {
+ MUTEX_NAME=can_suspend sxmo_mutex.sh free "Proximity lock is running"
sxmo_screenlock.sh "$INITIALSTATE"
exit 0
}
-
INITIALSTATE="$(sxmo_screenlock.sh getCurState)"
trap 'finish' TERM INT
+MUTEX_NAME=can_suspend sxmo_mutex.sh lock "Proximity lock is running"
+
proximity_raw_bus="$(find /sys/devices/platform/soc -name 'in_proximity_raw')"
distance() {
cat "$proximity_raw_bus"
M scripts/core/sxmo_rtcwake.sh => scripts/core/sxmo_rtcwake.sh +5 -15
@@ 3,22 3,12 @@
# shellcheck source=configs/profile.d/sxmo_init.sh
. /etc/profile.d/sxmo_init.sh
-finish() {
- if grep -q crust "$SXMO_LASTSTATE" \
- && grep -q rtc "$SXMO_UNSUSPENDREASONFILE" \
- && [ "$(sxmo_screenlock.sh getCurState)" != "unlock" ]; then
- WAKEPROCS=$(pgrep -f sxmo_rtcwake.sh | wc -l)
- if [ "$WAKEPROCS" -gt 2 ]; then
- #each process also spawns a blink subprocess, so we check if there are more than two rather than one:
- echo "sxmo_rtcwake: returning without crust, other sxmo_rtcwake process is still running ($(date))" >&2
- else
- echo "sxmo_rtcwake: going back to crust ($(date))" >&2
- sxmo_screenlock.sh crust
- fi
- else
- echo "sxmo_rtcwake: returning without crust ($(date))" >&2
- fi
+# We can have multiple cronjobs at the same time
+MUTEX_NAME=can_suspend sxmo_mutex.sh lock "Executing cronjob"
+MUTEX_NAME=can_suspend sxmo_mutex.sh free "Waiting for cronjob"
+finish() {
+ MUTEX_NAME=can_suspend sxmo_mutex.sh free "Executing cronjob"
exit 0
}
M scripts/core/sxmo_screenlock.sh => scripts/core/sxmo_screenlock.sh +7 -2
@@ 85,8 85,6 @@ crust() {
getCurState > "$SXMO_LASTSTATE"
- sxmo_led.sh blink red
-
saveAllEventCounts
sxmo_hooks.sh presuspend
@@ 99,6 97,9 @@ crust() {
if [ -z "$suspend_time" ] || [ "$suspend_time" -gt "$YEARS8_TO_SEC" ]; then
suspend_time="$YEARS8_TO_SEC"
fi
+
+ sxmo_led.sh blink red
+
if [ "$suspend_time" -gt 0 ]; then
sxmo_log "real crusting now (suspendtime=$suspend_time)"
rtcwake -m mem -s "$suspend_time" >&2
@@ 114,6 115,10 @@ crust() {
sxmo_log "woke up from crust (reason=$UNSUSPENDREASON)"
+ if [ "$UNSUSPENDREASON" = "rtc" ]; then
+ MUTEX_NAME=can_suspend sxmo_mutex.sh lock "Waiting for cronjob"
+ fi
+
sxmo_hooks.sh postwake "$UNSUSPENDREASON"
}
D scripts/core/sxmo_screenlock_deeper.sh => scripts/core/sxmo_screenlock_deeper.sh +0 -31
@@ 1,31 0,0 @@
-#!/bin/sh
-
-# this script goal is to move the screen lock state from lock to off then crust
-
-if [ "$1" = "--idle" ]; then
- sxmo_hooks.sh is_idle >/dev/null || exit
-fi
-
-initial_state="$(sxmo_screenlock.sh getCurState)"
-case "$initial_state" in
- unlock)
- target_state=lock
- case "$SXMO_WM" in
- sway)
- swaymsg mode default -q
- ;;
- esac
- ;;
- lock)
- target_state=off
- ;;
- off)
- target_state=crust
- ;;
-esac
-
-if [ "crust" = "$target_state" ] && ! sxmo_hooks.sh can_suspend >/dev/null; then
- exit
-fi
-
-sxmo_screenlock.sh "$target_state"