Rely on /sys/power/wake_lock
Signed-off-by: Willow Barraco <contact@willowbarraco.fr> Signed-off-by: Peter John Hartman <peterjohnhartman@gmail.com>
This commit is contained in:

committed by
Peter John Hartman

parent
b204be1d86
commit
89a77e6057
8
Makefile
8
Makefile
@@ -11,7 +11,8 @@ OPENRC:=1
|
||||
CC ?= $(CROSS_COMPILE)gcc
|
||||
PROGRAMS = \
|
||||
programs/sxmo_aligned_sleep \
|
||||
programs/sxmo_vibrate
|
||||
programs/sxmo_vibrate \
|
||||
programs/sxmo_wakeafter
|
||||
|
||||
all: $(PROGRAMS)
|
||||
|
||||
@@ -23,6 +24,9 @@ shellcheck:
|
||||
programs/%: programs/%.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $<
|
||||
|
||||
programs/sxmo_wakeafter: programs/sxmo_wakeafter.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -Wl,--no-as-needed -lcap -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f programs/sxmo_aligned_sleep programs/sxmo_vibrate
|
||||
|
||||
@@ -73,6 +77,8 @@ install-scripts: $(PROGRAMS)
|
||||
|
||||
install -D programs/sxmo_aligned_sleep $(DESTDIR)$(PREFIX)/bin/
|
||||
install -D programs/sxmo_vibrate $(DESTDIR)$(PREFIX)/bin/
|
||||
install -D programs/sxmo_wakeafter $(DESTDIR)$(PREFIX)/bin/
|
||||
setcap 'cap_block_suspend=p cap_wake_alarm=p' $(DESTDIR)$(PREFIX)/bin/sxmo_wakeafter
|
||||
|
||||
find $(DESTDIR)$(PREFIX)/share/sxmo/default_hooks/ -type f -exec ./setup_config_version.sh "{}" \;
|
||||
find $(DESTDIR)$(PREFIX)/share/sxmo/appcfg/ -type f -exec ./setup_config_version.sh "{}" \;
|
||||
|
@@ -2,6 +2,10 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2022 Sxmo Contributors
|
||||
|
||||
if [ -f /sys/power/wake_lock ]; then
|
||||
echo not_screenoff | doas tee -a /sys/power/wake_lock > /dev/null
|
||||
fi
|
||||
|
||||
# Go to locker after 5 minutes of inactivity
|
||||
if [ -e "$XDG_CACHE_HOME/sxmo/sxmo.noidle" ]; then
|
||||
sxmo_daemons.sh stop idle_locker
|
||||
|
@@ -6,14 +6,8 @@
|
||||
# shellcheck source=scripts/core/sxmo_common.sh
|
||||
. sxmo_common.sh
|
||||
|
||||
# UNSUSPENDREASON="$1"
|
||||
|
||||
#The UNSUSPENDREASON can be "usb power", "cover", "rtc" (real-time clock
|
||||
#periodic wakeup) or "button". You will likely want to check against this and
|
||||
#decide what to do
|
||||
|
||||
light -S "$(cat "$XDG_RUNTIME_DIR"/sxmo.brightness.presuspend.state)"
|
||||
|
||||
sxmo_hook_unlock.sh
|
||||
if [ -f /sys/power/wake_lock ]; then
|
||||
echo "stay_awake ${SXMO_UNLOCK_IDLE_TIME:-120}000000000" | doas tee -a /sys/power/wake_lock > /dev/null
|
||||
fi
|
||||
|
||||
# Add here whatever you want to do
|
||||
|
@@ -1,29 +0,0 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2022 Sxmo Contributors
|
||||
|
||||
# This script is called prior to suspending
|
||||
|
||||
# include common definitions
|
||||
# shellcheck source=scripts/core/sxmo_common.sh
|
||||
. sxmo_common.sh
|
||||
|
||||
pkill clickclack
|
||||
sxmo_keyboard.sh close
|
||||
pkill mpv #if any audio/video is playing, kill it (it might stutter otherwise)
|
||||
|
||||
case "$SXMO_WM" in
|
||||
dwm)
|
||||
sxmo_dmenu.sh close
|
||||
;;
|
||||
esac
|
||||
|
||||
printf "SUSPEND" > "$SXMO_STATE"
|
||||
sxmo_hook_statusbar.sh state_change
|
||||
|
||||
# store brightness state and set it to zero
|
||||
light > "$XDG_RUNTIME_DIR"/sxmo.brightness.presuspend.state
|
||||
light -S 0
|
||||
sleep 1s # give statusbar a second to update
|
||||
|
||||
# Add here whatever you want to do
|
@@ -11,6 +11,10 @@
|
||||
sxmo_log "transitioning to stage unlock"
|
||||
printf unlock > "$SXMO_STATE"
|
||||
|
||||
if [ -f /sys/power/wake_lock ]; then
|
||||
echo "stay_awake ${SXMO_UNLOCK_IDLE_TIME:-120}000000000" | doas tee -a /sys/power/wake_lock > /dev/null
|
||||
fi
|
||||
|
||||
sxmo_hook_statusbar.sh state_change &
|
||||
|
||||
sxmo_wm.sh dpms off
|
||||
@@ -18,14 +22,11 @@ sxmo_wm.sh inputevent touchscreen on
|
||||
sxmo_wm.sh inputevent stylus on
|
||||
superctl start sxmo_hook_lisgd
|
||||
|
||||
# suspend after 30s
|
||||
# the periodic mutex check is necessary to 'free' old mutex, I think.
|
||||
if ! [ -e "$XDG_CACHE_HOME/sxmo/sxmo.nosuspend" ]; then
|
||||
sxmo_daemons.sh start idle_locker sxmo_idle.sh -w \
|
||||
timeout "${SXMO_UNLOCK_IDLE_TIME:-120}" 'sxmo_daemons.sh start crustin sxmo_run_periodically.sh 5 sh -c "sxmo_hook_check_state_mutexes.sh && exec sxmo_mutex.sh can_suspend holdexec sxmo_suspend.sh"' \
|
||||
resume 'sxmo_daemons.sh stop crustin' \
|
||||
timeout "$((${SXMO_UNLOCK_IDLE_TIME:-120}+10))" 'sxmo_daemons.sh start periodic_state_mutex_check sxmo_run_periodically.sh 10 sxmo_hook_check_state_mutexes.sh' \
|
||||
resume 'sxmo_daemons.sh stop periodic_state_mutex_check'
|
||||
fi
|
||||
sxmo_daemons.sh start periodic_state_mutex_check sxmo_run_periodically.sh 10 sxmo_hook_check_state_mutexes.sh
|
||||
|
||||
# suspend after if no activity after 120s
|
||||
sxmo_daemons.sh start idle_locker sxmo_idle.sh -w \
|
||||
timeout "1" '' \
|
||||
resume "echo \"stay_awake ${SXMO_UNLOCK_IDLE_TIME:-120}000000000\" | doas tee -a /sys/power/wake_lock > /dev/null"
|
||||
|
||||
wait
|
||||
|
@@ -5,46 +5,43 @@
|
||||
# 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
|
||||
|
||||
# WARNING: if you remove an entry, be sure to run `sxmo_mutex.sh can_suspend
|
||||
# free "entry name"` afterwards.
|
||||
|
||||
# include common definitions
|
||||
# shellcheck source=scripts/core/sxmo_common.sh
|
||||
. sxmo_common.sh
|
||||
|
||||
lock_suspend_mutex() {
|
||||
if ! sxmo_mutex.sh can_suspend lockedby "$1"; then
|
||||
sxmo_mutex.sh can_suspend lock "$1"
|
||||
fi
|
||||
echo "$1" | doas tee -a /sys/power/wake_lock > /dev/null
|
||||
sxmo_debug "lock \"$1\""
|
||||
}
|
||||
|
||||
free_suspend_mutex() {
|
||||
sxmo_mutex.sh can_suspend free "$1"
|
||||
echo "$1" | doas tee -a /sys/power/wake_unlock > /dev/null 2>&1
|
||||
sxmo_debug "free \"$1\""
|
||||
}
|
||||
|
||||
cleanup_main_mutex() {
|
||||
free_suspend_mutex "Checking some mutexes"
|
||||
free_suspend_mutex "checking_mutexes"
|
||||
exit 0
|
||||
}
|
||||
|
||||
exec 3<> "${XDG_RUNTIME_DIR:-$HOME}/sxmo.checkstatemutexes.lock"
|
||||
flock -x 3
|
||||
|
||||
lock_suspend_mutex "Checking some mutexes"
|
||||
lock_suspend_mutex "checking_mutexes"
|
||||
trap 'cleanup_main_mutex' TERM INT EXIT
|
||||
|
||||
# ongoing_call
|
||||
if pgrep -f sxmo_modemcall.sh > /dev/null; then
|
||||
lock_suspend_mutex "Ongoing call"
|
||||
lock_suspend_mutex "ongoing_call"
|
||||
else
|
||||
free_suspend_mutex "Ongoing call"
|
||||
free_suspend_mutex "ongoing_call"
|
||||
fi
|
||||
|
||||
# hotspot active
|
||||
if nmcli -t c show --active | grep ^Hotspot; then
|
||||
lock_suspend_mutex "Hotspot is active"
|
||||
lock_suspend_mutex "hotspot_active"
|
||||
else
|
||||
free_suspend_mutex "Hotspot is active"
|
||||
free_suspend_mutex "hotspot_active"
|
||||
fi
|
||||
|
||||
ssh_connected() {
|
||||
@@ -57,44 +54,44 @@ ssh_connected() {
|
||||
|
||||
# active_ssh
|
||||
if ssh_connected; then
|
||||
lock_suspend_mutex "SSH is connected"
|
||||
lock_suspend_mutex "ssh_connected"
|
||||
else
|
||||
free_suspend_mutex "SSH is connected"
|
||||
free_suspend_mutex "ssh_connected"
|
||||
fi
|
||||
|
||||
# active_mosh
|
||||
if command -v mosh-server > /dev/null && pgrep -f mosh-server > /dev/null; then
|
||||
lock_suspend_mutex "Mosh is listening"
|
||||
lock_suspend_mutex "mosh_listening"
|
||||
else
|
||||
free_suspend_mutex "Mosh is listening"
|
||||
free_suspend_mutex "mosh_listening"
|
||||
fi
|
||||
|
||||
# playing_mpc
|
||||
if command -v mpc > /dev/null && mpc status 2>/dev/null | grep -q '\[playing\]'; then
|
||||
lock_suspend_mutex "MPD is playing music"
|
||||
lock_suspend_mutex "mpd_playing"
|
||||
else
|
||||
free_suspend_mutex "MPD is playing music"
|
||||
free_suspend_mutex "mpd_playing"
|
||||
fi
|
||||
|
||||
# mpris compatible media player
|
||||
if command -v playerctl > /dev/null; then
|
||||
if test "$(playerctl status 2>/dev/null)" = "Playing"; then
|
||||
lock_suspend_mutex "MPRIS client is playing"
|
||||
lock_suspend_mutex "mpris_playing"
|
||||
else
|
||||
free_suspend_mutex "MPRIS client is playing"
|
||||
free_suspend_mutex "mpris_playing"
|
||||
fi
|
||||
fi
|
||||
|
||||
# photos_processing
|
||||
if pgrep -f postprocess > /dev/null; then
|
||||
lock_suspend_mutex "Camera postprocessing"
|
||||
lock_suspend_mutex "camera_postprocessing"
|
||||
else
|
||||
free_suspend_mutex "Camera postprocessing"
|
||||
free_suspend_mutex "camera_postprocessing"
|
||||
fi
|
||||
|
||||
# auto_suspend
|
||||
if [ -e "$XDG_CACHE_HOME/sxmo/sxmo.nosuspend" ]; then
|
||||
lock_suspend_mutex "Manually disabled"
|
||||
lock_suspend_mutex "manually_disabled"
|
||||
else
|
||||
free_suspend_mutex "Manually disabled"
|
||||
free_suspend_mutex "manually_disabled"
|
||||
fi
|
||||
|
@@ -85,7 +85,7 @@ case "$WMCLASS" in
|
||||
$icon_clk Change Timezone ^ 1 ^ sxmo_timezonechange.sh
|
||||
$icon_zzz Auto-suspend $(
|
||||
[ -e "$XDG_CACHE_HOME"/sxmo/sxmo.nosuspend ] && printf "%s" "$icon_tof" || printf "%s" "$icon_ton"
|
||||
) ^ 1 ^ (rm $XDG_CACHE_HOME/sxmo/sxmo.nosuspend || touch $XDG_CACHE_HOME/sxmo/sxmo.nosuspend); sxmo_hook_check_state_mutexes.sh
|
||||
) ^ 1 ^ (rm $XDG_CACHE_HOME/sxmo/sxmo.nosuspend || touch $XDG_CACHE_HOME/sxmo/sxmo.nosuspend)
|
||||
$icon_zzz Auto-screen-off $(
|
||||
[ -e "$XDG_CACHE_HOME/sxmo/sxmo.noidle" ] && printf "%s" "$icon_tof" || printf "%s" "$icon_ton"
|
||||
) ^ 1 ^ (rm $XDG_CACHE_HOME/sxmo/sxmo.noidle || touch $XDG_CACHE_HOME/sxmo/sxmo.noidle) && sxmo_hook_unlock.sh
|
||||
@@ -109,7 +109,6 @@ case "$WMCLASS" in
|
||||
CHOICES="
|
||||
$icon_lck Lock ^ 0 ^ sxmo_hook_lock.sh
|
||||
$icon_lck Lock (Screen off) ^ 0 ^ sxmo_hook_screenoff.sh
|
||||
$icon_zzz Suspend ^ 0 ^ sxmo_hook_screenoff.sh && sxmo_suspend.sh
|
||||
$icon_out Logout ^ 0 ^ confirm Logout && sxmo_power.sh logout
|
||||
$([ -f "$(xdg_data_path xsessions/sxmo.desktop)" ] &&
|
||||
[ -f "$(xdg_data_path wayland-sessions/swmo.desktop)" ] &&
|
||||
|
@@ -5,23 +5,10 @@
|
||||
# shellcheck source=scripts/core/sxmo_common.sh
|
||||
. sxmo_common.sh
|
||||
|
||||
YEARS8_TO_SEC=268435455
|
||||
|
||||
if ! command -v mnc > /dev/null; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
time="$(crontab -l | grep sxmo_rtcwake | mnc)"
|
||||
crontab -l | grep sxmo_rtcwake | mnc
|
||||
|
||||
# don't return time if it's too far in the future
|
||||
if [ "$time" -ge "$YEARS8_TO_SEC" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Exit status 1 indicates that there is a cron job soon
|
||||
if [ "$time" -lt 10 ]; then
|
||||
sxmo_log "next cron time ($time) is too soon"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "$((time - 10))"
|
||||
|
@@ -63,6 +63,11 @@ esac
|
||||
# To setup initial lock state
|
||||
sxmo_hook_unlock.sh
|
||||
|
||||
# Turn on auto-suspend
|
||||
if [ -w "/sys/power/autosleep" ] && [ -f "/sys/power/wake_lock" ]; then
|
||||
superctl start sxmo_autosuspend
|
||||
fi
|
||||
|
||||
# Turn on lisgd
|
||||
superctl start sxmo_hook_lisgd
|
||||
|
||||
|
@@ -12,6 +12,10 @@ flock -x 3
|
||||
sxmo_log "transitioning to stage lock"
|
||||
printf lock > "$SXMO_STATE"
|
||||
|
||||
if [ -f /sys/power/wake_lock ]; then
|
||||
echo not_screenoff | doas tee -a /sys/power/wake_lock > /dev/null
|
||||
fi
|
||||
|
||||
# This hook is called when the system reaches a locked state
|
||||
|
||||
sxmo_led.sh blink blue &
|
||||
|
@@ -14,9 +14,9 @@ UNSUSPENDREASON="$1"
|
||||
|
||||
# stay awake if modem has crashed for 30s to give modem time to recover
|
||||
modemloop() {
|
||||
sxmo_mutex.sh can_suspend lock "! Modem crashed."
|
||||
echo "modem_crashed" | doas tee -a /sys/power/wake_lock > /dev/null
|
||||
sleep 30s
|
||||
sxmo_mutex.sh can_suspend free "! Modem crashed."
|
||||
echo "modem_crashed" | doas tee -a /sys/power/wake_unlock > /dev/null
|
||||
}
|
||||
|
||||
if [ "$UNSUSPENDREASON" = "modem" ]; then
|
||||
|
@@ -1,25 +0,0 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2022 Sxmo Contributors
|
||||
|
||||
# This script is called prior to suspending
|
||||
|
||||
# include common definitions
|
||||
# shellcheck source=scripts/core/sxmo_common.sh
|
||||
. sxmo_common.sh
|
||||
|
||||
sxmo_daemons.sh stop periodic_blink
|
||||
|
||||
pkill clickclack
|
||||
sxmo_keyboard.sh close
|
||||
pkill -INT mpv #if any audio/video is playing, kill it (it might stutter otherwise)
|
||||
|
||||
case "$SXMO_WM" in
|
||||
sway)
|
||||
makoctl dismiss -a # close all popups
|
||||
;;
|
||||
dwm)
|
||||
sxmo_dmenu.sh close
|
||||
dunstctl close all # close all popups
|
||||
;;
|
||||
esac
|
@@ -31,15 +31,19 @@ case "$SXMO_WM" in
|
||||
;;
|
||||
esac
|
||||
|
||||
sxmo_hook_check_state_mutexes.sh
|
||||
|
||||
# Start a periodic daemon (8s) "try to go to crust" after 8 seconds
|
||||
# Start a periodic daemon (2s) blink after 5 seconds
|
||||
# Resume tasks stop daemons
|
||||
sxmo_daemons.sh start idle_locker sxmo_idle.sh -w \
|
||||
timeout 8 'sxmo_daemons.sh start going_deeper sxmo_run_periodically.sh 30 sh -c "sxmo_hook_check_state_mutexes.sh && exec sxmo_mutex.sh can_suspend holdexec sxmo_suspend.sh"' \
|
||||
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' \
|
||||
timeout 2 'sxmo_daemons.sh start periodic_blink sxmo_run_periodically.sh 2 sxmo_led.sh blink red blue' \
|
||||
resume 'sxmo_daemons.sh stop periodic_blink' \
|
||||
timeout 12 'sxmo_daemons.sh start periodic_state_mutex_check sxmo_run_periodically.sh 10 sxmo_hook_check_state_mutexes.sh' \
|
||||
timeout 10 'sxmo_daemons.sh start periodic_state_mutex_check sxmo_run_periodically.sh 10 sxmo_hook_check_state_mutexes.sh' \
|
||||
resume 'sxmo_daemons.sh stop periodic_state_mutex_check'
|
||||
|
||||
wait
|
||||
|
||||
if [ -f /sys/power/wake_unlock ]; then
|
||||
echo not_screenoff | doas tee -a /sys/power/wake_unlock > /dev/null
|
||||
fi
|
||||
|
@@ -14,6 +14,10 @@ flock -x 3
|
||||
sxmo_log "transitioning to stage unlock"
|
||||
printf unlock > "$SXMO_STATE"
|
||||
|
||||
if [ -f /sys/power/wake_lock ]; then
|
||||
echo not_screenoff | doas tee -a /sys/power/wake_lock > /dev/null
|
||||
fi
|
||||
|
||||
sxmo_led.sh blink red green &
|
||||
sxmo_hook_statusbar.sh state_change &
|
||||
|
||||
@@ -51,7 +55,4 @@ else
|
||||
esac
|
||||
fi
|
||||
|
||||
sxmo_daemons.sh start periodic_state_mutex_check \
|
||||
sxmo_run_aligned.sh 60 sxmo_hook_check_state_mutexes.sh
|
||||
|
||||
wait
|
||||
|
@@ -16,3 +16,5 @@ permit nopass :wheel as root cmd systemctl args start eg25-manager
|
||||
permit nopass :wheel as root cmd systemctl args stop eg25-manager
|
||||
permit nopass :wheel as root cmd systemctl args start ModemManager
|
||||
permit nopass :wheel as root cmd systemctl args stop ModemManager
|
||||
permit nopass :wheel as root cmd tee args -a /sys/power/wake_lock
|
||||
permit nopass :wheel as root cmd tee args -a /sys/power/wake_unlock
|
||||
|
7
configs/superd/services/sxmo_autosuspend.service
Normal file
7
configs/superd/services/sxmo_autosuspend.service
Normal file
@@ -0,0 +1,7 @@
|
||||
[Unit]
|
||||
Description=daemon for autosuspending
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=always
|
||||
ExecStart=/usr/bin/sxmo_autosuspend.sh
|
130
programs/sxmo_wakeafter.c
Normal file
130
programs/sxmo_wakeafter.c
Normal file
@@ -0,0 +1,130 @@
|
||||
#include <errno.h> // error handling
|
||||
#include <stdint.h> // uint64_t type
|
||||
#include <stdio.h> // dprintf
|
||||
#include <stdlib.h> // strtol, exit
|
||||
#include <string.h> // strerror
|
||||
#include <sys/timerfd.h> // timers
|
||||
#include <unistd.h> // read
|
||||
#include <sys/epoll.h> // epoll_*
|
||||
#include <sys/capability.h> // cap_*
|
||||
|
||||
#define MAX_EVENTS 1
|
||||
|
||||
#define try(func, args...) { \
|
||||
if (-1 == func(args)) { \
|
||||
perror(#func); \
|
||||
return 1; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define eprintf(...) fprintf (stderr, __VA_ARGS__)
|
||||
|
||||
void error(char *message, int err) {
|
||||
dprintf(2, "%s: %s\n", message, strerror(err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void usage(char *name) {
|
||||
eprintf(
|
||||
"%s: <seconds> <command>\n"
|
||||
"\tRun <command> after <seconds> or after a suspension wake up. "
|
||||
"Hold the system awake until the command finished\n",
|
||||
name
|
||||
);
|
||||
}
|
||||
|
||||
void check_cap_avail(cap_value_t cap) {
|
||||
if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
|
||||
fprintf(stderr, "ERROR: %s isn't available on your system\n", cap_to_name(cap));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int check_perimsions() {
|
||||
const cap_value_t cap_list[2] = {CAP_BLOCK_SUSPEND, CAP_WAKE_ALARM};
|
||||
|
||||
check_cap_avail(CAP_BLOCK_SUSPEND);
|
||||
check_cap_avail(CAP_WAKE_ALARM);
|
||||
|
||||
cap_t caps = cap_get_proc();
|
||||
if (caps == NULL) {
|
||||
perror("cap_get_proc");
|
||||
return 1;
|
||||
}
|
||||
|
||||
try(cap_set_flag, caps, CAP_EFFECTIVE, 2, cap_list, CAP_SET);
|
||||
|
||||
if (-1 == cap_set_proc(caps)) {
|
||||
perror("cap_set_proc");
|
||||
return 1;
|
||||
}
|
||||
|
||||
try(cap_free, caps);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
uint64_t buf;
|
||||
long duration = -1;
|
||||
int time_fd, epollfd;
|
||||
|
||||
struct epoll_event ev, events[MAX_EVENTS];
|
||||
|
||||
struct timespec now;
|
||||
struct itimerspec time = {
|
||||
.it_value = { .tv_sec = 0, .tv_nsec = 0 },
|
||||
.it_interval = { .tv_sec = 0, .tv_nsec = 0 }
|
||||
};
|
||||
|
||||
// Check permissions
|
||||
if (check_perimsions()) {
|
||||
fprintf(stderr, "Hint: make sure this executeable has the "
|
||||
"cap_block_suspend and cap_wake_alarm privilages\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Process arguments
|
||||
if (argc != 3) {
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
duration = strtol(argv[1], NULL, 0);
|
||||
|
||||
if (duration <= 0 || errno == ERANGE) {
|
||||
usage(argv[0]);
|
||||
eprintf("Error: seconds must be a positive integer\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create timer
|
||||
if ((time_fd = timerfd_create(CLOCK_REALTIME_ALARM, 0)) == -1)
|
||||
error("Failed to create timerfd", errno);
|
||||
|
||||
// Setup epoll
|
||||
epollfd = epoll_create1(0);
|
||||
ev.events = EPOLLIN | EPOLLWAKEUP;
|
||||
ev.data.fd = time_fd;
|
||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, time_fd, &ev);
|
||||
|
||||
// Calculate absolute time to wakeup
|
||||
try(clock_gettime, CLOCK_REALTIME, &now);
|
||||
time.it_value.tv_sec = now.tv_sec + duration;
|
||||
time.it_value.tv_nsec = now.tv_nsec;
|
||||
|
||||
/* if (timerfd_settime(time_fd, TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &time, NULL) == -1) { */
|
||||
try(timerfd_settime, time_fd, TFD_TIMER_ABSTIME, &time, NULL);
|
||||
|
||||
// Wait for timer
|
||||
int ret;
|
||||
do {
|
||||
ret = epoll_wait(epollfd, events, MAX_EVENTS, -1);
|
||||
if (ret == -1 && errno == EINTR) {
|
||||
eprintf("Woke up\n");
|
||||
break;
|
||||
}
|
||||
} while (ret < 1);
|
||||
|
||||
system(argv[2]);
|
||||
}
|
@@ -50,39 +50,53 @@ whichWake() {
|
||||
echo "button"
|
||||
}
|
||||
|
||||
sxmo_log "going to suspend to crust"
|
||||
|
||||
saveAllEventCounts
|
||||
|
||||
sxmo_hook_presuspend.sh
|
||||
|
||||
sxmo_led.sh blink red
|
||||
|
||||
if suspend_time="$(sxmo_hook_mnc.sh)"; then
|
||||
sxmo_log "calling suspend with suspend_time <$suspend_time>"
|
||||
|
||||
start="$(date "+%s")"
|
||||
sxmo_hook_suspend.sh "$suspend_time"
|
||||
|
||||
#We woke up again
|
||||
time_spent="$(( $(date "+%s") - start ))"
|
||||
|
||||
if [ "$suspend_time" -gt 0 ] && [ "$((time_spent + 10))" -ge "$suspend_time" ]; then
|
||||
UNSUSPENDREASON="rtc"
|
||||
else
|
||||
UNSUSPENDREASON="$(whichWake)"
|
||||
finish() {
|
||||
if [ -n "$INITIAL" ]; then
|
||||
echo "$INITIAL" > /sys/power/autosleep
|
||||
fi
|
||||
else
|
||||
sxmo_log "fake suspend (suspend_time ($suspend_time) less than zero)"
|
||||
UNSUSPENDREASON=rtc # we fake the crust for those seconds
|
||||
kill "$WAKEPID"
|
||||
exit
|
||||
}
|
||||
|
||||
autosuspend() {
|
||||
YEARS8_TO_SEC=268435455
|
||||
|
||||
INITIAL="$(cat /sys/power/autosleep)"
|
||||
trap 'finish' TERM INT EXIT
|
||||
|
||||
while : ; do
|
||||
# necessary?
|
||||
echo "$INITIAL" > /sys/power/autosleep
|
||||
|
||||
suspend_time=99999999 # far away
|
||||
mnc="$(sxmo_hook_mnc.sh)"
|
||||
if [ -n "$mnc" ] && [ "$mnc" -gt 0 ] && [ "$mnc" -lt "$YEARS8_TO_SEC" ]; then
|
||||
if [ "$mnc" -le 15 ]; then # cronjob imminent
|
||||
echo "waiting_cronjob" | doas tee -a /sys/power/wake_lock > /dev/null
|
||||
suspend_time=$((mnc + 1)) # to arm the following one
|
||||
else
|
||||
suspend_time=$((mnc - 10))
|
||||
fi
|
||||
fi
|
||||
|
||||
sxmo_wakeafter "$suspend_time" "sxmo_autosuspend.sh wokeup" &
|
||||
WAKEPID=$!
|
||||
sleep 1 # wait for it to epoll pwait
|
||||
|
||||
echo mem > /sys/power/autosleep
|
||||
wait
|
||||
done
|
||||
}
|
||||
|
||||
wokeup() {
|
||||
# 10s basic hold
|
||||
echo "woke_up 10000000000" | doas tee -a /sys/power/wake_lock > /dev/null
|
||||
|
||||
sxmo_hook_postwake.sh
|
||||
}
|
||||
|
||||
if [ -z "$*" ]; then
|
||||
set -- autosuspend
|
||||
fi
|
||||
|
||||
echo "$UNSUSPENDREASON" > "$SXMO_UNSUSPENDREASONFILE"
|
||||
|
||||
sxmo_log "woke up from crust (reason=$UNSUSPENDREASON)"
|
||||
|
||||
if [ "$UNSUSPENDREASON" = "rtc" ]; then
|
||||
sxmo_mutex.sh can_suspend lock "Waiting for cronjob"
|
||||
fi
|
||||
|
||||
sxmo_hook_postwake.sh "$UNSUSPENDREASON"
|
||||
"$@"
|
@@ -6,12 +6,12 @@
|
||||
. sxmo_common.sh
|
||||
|
||||
free_mutex() {
|
||||
sxmo_mutex.sh can_suspend free "Playing with leds"
|
||||
echo "playing_with_leds" | doas tee -a /sys/power/wake_unlock > /dev/null
|
||||
exit
|
||||
}
|
||||
|
||||
ensure_mutex() {
|
||||
sxmo_mutex.sh can_suspend lock "Playing with leds"
|
||||
echo "playing_with_leds" | doas tee -a /sys/power/wake_lock > /dev/null
|
||||
trap 'free_mutex' TERM INT
|
||||
}
|
||||
|
||||
|
@@ -1,92 +0,0 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2022 Sxmo Contributors
|
||||
|
||||
# include common definitions
|
||||
# shellcheck source=scripts/core/sxmo_common.sh
|
||||
. sxmo_common.sh
|
||||
|
||||
set -e
|
||||
|
||||
MUTEX_NAME="$1"
|
||||
shift
|
||||
|
||||
ROOT_DIR="${XDG_RUNTIME_DIR:-/dev/shm/user/$(id -u)}"/sxmo_mutex
|
||||
REASON_FILE="$ROOT_DIR/$MUTEX_NAME"
|
||||
mkdir -p "$(dirname "$REASON_FILE")"
|
||||
exec 3>"$REASON_FILE.lock"
|
||||
touch "$REASON_FILE"
|
||||
|
||||
lock() {
|
||||
flock 3
|
||||
REASON="$1"
|
||||
printf "%s\n" "$REASON" >> "$REASON_FILE"
|
||||
sxmo_debug "lock \"$MUTEX_NAME\", total: $(wc -l < "$REASON_FILE"), \"$REASON\""
|
||||
}
|
||||
|
||||
free() {
|
||||
flock 3
|
||||
REASON="$1"
|
||||
grep -xnm1 "$REASON" "$REASON_FILE" | \
|
||||
cut -d: -f1 | \
|
||||
xargs -r -I{} sed -i '{}d' "$REASON_FILE"
|
||||
sxmo_debug "free \"$MUTEX_NAME\", total: $(wc -l < "$REASON_FILE"), \"$REASON\""
|
||||
}
|
||||
|
||||
lockedby() {
|
||||
sxmo_debug "Lockedby: $1"
|
||||
grep -qxm1 "$1" "$REASON_FILE"
|
||||
}
|
||||
|
||||
freeall() {
|
||||
printf "" > "$REASON_FILE"
|
||||
sxmo_hook_statusbar.sh lockedby
|
||||
sxmo_log "freeall($MUTEX_NAME)"
|
||||
}
|
||||
|
||||
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=$!
|
||||
|
||||
# shellcheck disable=SC2317
|
||||
finish() {
|
||||
kill "$NOTIFYPID" 2>/dev/null
|
||||
rm "$FIFO"
|
||||
exit 0
|
||||
}
|
||||
trap 'finish' TERM INT EXIT
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
while read -r _; do
|
||||
if ! [ -s "$REASON_FILE" ]; then
|
||||
exit 0
|
||||
fi
|
||||
done < "$FIFO"
|
||||
}
|
||||
|
||||
holdexec() {
|
||||
# shellcheck disable=SC2317
|
||||
finish() {
|
||||
kill "$HOLDPID" 2>/dev/null
|
||||
exit
|
||||
}
|
||||
trap 'finish' TERM INT
|
||||
|
||||
hold &
|
||||
HOLDPID=$!
|
||||
wait "$HOLDPID"
|
||||
|
||||
"$@"
|
||||
}
|
||||
|
||||
"$@"
|
@@ -2,10 +2,4 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2022 Sxmo Contributors
|
||||
|
||||
# include common definitions
|
||||
# shellcheck source=scripts/core/sxmo_common.sh
|
||||
. sxmo_common.sh
|
||||
|
||||
sxmo_mutex.sh can_suspend list
|
||||
|
||||
tail -f "$XDG_STATE_HOME"/sxmo.log | stdbuf -oL grep 'sxmo_mutex.sh'
|
||||
watch 'cat /sys/power/wake_lock | tr " " "\n"'
|
||||
|
@@ -19,7 +19,7 @@ finish() {
|
||||
# (see static const int stk3310_ps_max[4])
|
||||
printf 6553 > "$prox_path/events/in_proximity_thresh_rising_value"
|
||||
|
||||
sxmo_mutex.sh can_suspend free "Proximity lock is running"
|
||||
echo "proximity_lock_running" | doas tee -a /sys/power/wake_unlock > /dev/null
|
||||
sxmo_daemons.sh start state_change_bar sxmo_hook_statusbar.sh state_change
|
||||
|
||||
exec sxmo_hook_"$INITIALSTATE".sh
|
||||
@@ -50,8 +50,7 @@ trap 'finish' TERM INT
|
||||
|
||||
sxmo_daemons.sh stop idle_locker
|
||||
|
||||
sxmo_mutex.sh can_suspend lock "Proximity lock is running"
|
||||
sxmo_hook_statusbar.sh lockedby
|
||||
echo "proximity_lock_running" | doas tee -a /sys/power/wake_lock > /dev/null
|
||||
sxmo_daemons.sh start state_change_bar sxmo_hook_statusbar.sh state_change
|
||||
|
||||
# find the device
|
||||
|
@@ -8,13 +8,11 @@
|
||||
. sxmo_common.sh
|
||||
|
||||
# We can have multiple cronjobs at the same time
|
||||
sxmo_mutex.sh can_suspend lock "Executing cronjob"
|
||||
sxmo_mutex.sh can_suspend free "Waiting for cronjob"
|
||||
sxmo_hook_statusbar.sh lockedby
|
||||
echo "executing_cronjob" | doas tee -a /sys/power/wake_lock > /dev/null
|
||||
echo "waiting_cronjob" | doas tee -a /sys/power/wake_unlock > /dev/null
|
||||
|
||||
finish() {
|
||||
sxmo_mutex.sh can_suspend free "Executing cronjob"
|
||||
sxmo_hook_statusbar.sh lockedby
|
||||
echo "executing_cronjob" | doas tee -a /sys/power/wake_unlock > /dev/null
|
||||
exit 0
|
||||
}
|
||||
|
||||
|
@@ -18,7 +18,7 @@ fi
|
||||
# users can override this in sxmo_deviceprofile_mydevice.sh
|
||||
files="${SXMO_SYS_FILES:-"/sys/power/state /sys/power/mem_sleep /dev/rtc0"}"
|
||||
|
||||
for file in $files; do
|
||||
for file in $files /sys/power/autosleep; do
|
||||
[ -e "$file" ] && chmod a+rw "$file"
|
||||
done
|
||||
|
||||
|
@@ -34,7 +34,7 @@ update_nixos() {
|
||||
echo "Upgrade complete - reboot for all changes to take effect"
|
||||
}
|
||||
|
||||
sxmo_mutex.sh can_suspend lock "Upgrading"
|
||||
echo "upgrading" | doas tee -a /sys/power/wake_lock > /dev/null
|
||||
|
||||
case "$OS" in
|
||||
alpine|postmarketos) update_apk;;
|
||||
@@ -42,4 +42,4 @@ case "$OS" in
|
||||
nixos) update_nixos;;
|
||||
esac
|
||||
|
||||
sxmo_mutex.sh can_suspend free "Upgrading"
|
||||
echo "upgrading" | doas tee -a /sys/power/wake_unlock > /dev/null
|
||||
|
@@ -286,8 +286,6 @@ processmms() {
|
||||
fi
|
||||
}
|
||||
|
||||
sxmo_mutex.sh can_suspend lock "Modem is used"
|
||||
sxmo_hook_statusbar.sh lockedby
|
||||
echo "mms_processing" | doas tee -a /sys/power/wake_lock > /dev/null
|
||||
"$@"
|
||||
sxmo_mutex.sh can_suspend free "Modem is used"
|
||||
sxmo_hook_statusbar.sh lockedby
|
||||
echo "mms_processing" | doas tee -a /sys/power/wake_unlock > /dev/null
|
||||
|
@@ -260,8 +260,6 @@ checkfornewtexts() {
|
||||
done
|
||||
}
|
||||
|
||||
sxmo_mutex.sh can_suspend lock "Modem is used"
|
||||
sxmo_hook_statusbar.sh lockedby
|
||||
echo "modem_used" | doas tee -a /sys/power/wake_lock > /dev/null
|
||||
"$@"
|
||||
sxmo_mutex.sh can_suspend free "Modem is used"
|
||||
sxmo_hook_statusbar.sh lockedby
|
||||
echo "modem_used" | doas tee -a /sys/power/wake_unlock > /dev/null
|
||||
|
@@ -1,94 +0,0 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2022 Sxmo Contributors
|
||||
# shellcheck disable=SC2155
|
||||
export PATH="$PATH:$(pwd)/scripts/core:$(pwd)/configs/default_hooks"
|
||||
XDG_RUNTIME_DIR="$(mktemp -d)"
|
||||
XDG_STATE_HOME="$(mktemp -d)"
|
||||
export XDG_RUNTIME_DIR
|
||||
export XDG_STATE_HOME
|
||||
|
||||
Describe 'sxmo_mutex.sh'
|
||||
# Make sure we're running in a somewhat clean environment
|
||||
setup() {
|
||||
sh scripts/core/sxmo_mutex.sh shellspec_mutex freeall
|
||||
}
|
||||
|
||||
BeforeAll 'setup'
|
||||
|
||||
# TODO: refactor script so it can be included instead of calling it
|
||||
# Include scripts/core/sxmo_mutex.sh
|
||||
|
||||
It 'can list an empty lock'
|
||||
When call sh scripts/core/sxmo_mutex.sh shellspec_mutex list
|
||||
The output should equal ''
|
||||
The status should be success
|
||||
End
|
||||
|
||||
It 'can acquire a lock'
|
||||
When call sh scripts/core/sxmo_mutex.sh shellspec_mutex lock shellspec
|
||||
The status should be success
|
||||
End
|
||||
|
||||
It 'can list an acquired lock'
|
||||
When call sh scripts/core/sxmo_mutex.sh shellspec_mutex list
|
||||
The output should equal 'shellspec'
|
||||
End
|
||||
|
||||
It 'can free a lock'
|
||||
When call sh scripts/core/sxmo_mutex.sh shellspec_mutex free shellspec
|
||||
The status should be success
|
||||
End
|
||||
|
||||
It 'does not list a freed lock'
|
||||
When call sh scripts/core/sxmo_mutex.sh shellspec_mutex list
|
||||
The output should equal ''
|
||||
End
|
||||
|
||||
IDS="$(seq 1 100)"
|
||||
many_lock() {
|
||||
set -e
|
||||
|
||||
for id in $IDS; do
|
||||
sh scripts/core/sxmo_mutex.sh shellspec_mutex lock "$id" &
|
||||
done
|
||||
|
||||
wait
|
||||
}
|
||||
|
||||
It 'can handle concurrent locks'
|
||||
When call many_lock
|
||||
The status should be success
|
||||
End
|
||||
|
||||
It 'lists all concurrently added locks'
|
||||
list() {
|
||||
sh scripts/core/sxmo_mutex.sh shellspec_mutex list | sort
|
||||
}
|
||||
|
||||
When call list
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
The output should equal "$(printf "%s\n" $IDS | sort)"
|
||||
End
|
||||
|
||||
many_unlock() {
|
||||
set -e
|
||||
|
||||
for id in $IDS; do
|
||||
[ "$id" = 50 ] && continue
|
||||
sh scripts/core/sxmo_mutex.sh shellspec_mutex free "$id" &
|
||||
done
|
||||
|
||||
wait
|
||||
}
|
||||
|
||||
It 'can handle concurrent unlocks'
|
||||
When call many_unlock
|
||||
The status should be success
|
||||
End
|
||||
|
||||
It 'clears all locks after they are unlocked'
|
||||
When call sh scripts/core/sxmo_mutex.sh shellspec_mutex list
|
||||
The output should equal "50"
|
||||
End
|
||||
End
|
Reference in New Issue
Block a user