~mil/sxmo-tickets#235: 
Rework the way we pickup/discard

The notification way work but require multiple action when we actually got pretty little time.

We have to rework this part and ensure we can pickup easily when the phone wakup from crust and is screenlocked

Status
REPORTED
Submitter
~stacyharper
Assigned to
No-one
Submitted
3 months ago
Updated
20 hours ago
Labels
feature ready

~dinkocar 3 months ago

I agree. That is why I have implemented some automation during ringing. I will paste my ring, pickup and lisgdstart scripts here just as an idea. So, what it does is, when call is incoming, first it checks if phone is locked and then it checks proximity sensor. If there is nothing close to phone (screen is uncovered and phone is not in pocket or in a bag) screen is unlocked and turned on, and lisgd is restarted with special configuration for answering the phone (two fingers swipe up answers, two fingers swipe down rejects). After call is answered or rejected lisgd is restarted in normal mode. If call is missed, screen is returned in previous state (locked if it was locked, crust if it was in crust). Also during call proximity sensor is checked and when something is close (phone near ear) display is locked and off, and when proximity sensor is uncovered (user looking in screen), display is unlocked, turned on, and audio is routed to speaker. Also I am using mpv with ipc-server enabled, for ringing, because I am also using mpv for streaming internet radio, so this way, when I am listening to radio, and call comes in, radio is stopped and ringing starts. It can be used for any media actually, but currently I don't use any other media. Anyway, you can use this as starting point :) I have made only basic testing, so some bugs are expected. Also this implementation does not cover call waiting, and I have never tested what will happen if calls comes when one call is already in progress.

Ring script:


#!/usr/bin/env sh

# include common definitions
# shellcheck source=scripts/core/sxmo_common.sh
COMMON=$(which sxmo_common.sh)
. "$COMMON"

trap stopringing EXIT
trap 'exit 0' KILL TERM INT
trap 'LOCKED=false; MPVSTATE=closed' USR1

MPVDIR="$HOME/.config/mpv"
RINGTONE="/home/rade/.config/sxmo/ringtones/phone_ring.mp3"

LOCKED=false
[[ -n "$(pgrep sxmo_screenlock)" ]] && LOCKED=true
SCREENLOCKARG=$(ps | grep sxmo_screenlock | grep -v grep | awk '{ print $5 }')

finish() {
	echo "$1">&2
	notify-send "$1"
	exit 1
}

stopringing() {
    if [ "$MPVSTATE" = "running" ]; then
	    playradio.sh continue
    else
	    mpvctl.sh stop
    fi
    kill $VIBRATEPID
    sleep 1
    if [ -n "$MPVPID" ] && [ -n "$(ps | grep $MPVPID)" ]; then
        kill $MPVPID
    fi
    sxmo_lisgdstart.sh
    [[ "$LOCKED" == "true" ]] && sxmo_lock.sh $SCREENLOCKARG &
}

incallmonitor() {
    CALLRINGING=$(mmcli -m "$(modem_n)" --voice-list-calls)
    if [ "$CALLRINGING" = "No calls were found" ]; then
	exit 1
    fi
}

modem_n() {
    MODEMS="$(mmcli -L)"
    echo "$MODEMS" | grep -qoE 'Modem\/([0-9]+)' || finish "Couldn't find modem - is your modem enabled?"
    echo "$MODEMS" | grep -oE 'Modem\/([0-9]+)' | cut -d'/' -f2
}

getproximity() {
	echo $(cat /sys/bus/iio/devices/iio:device1/in_proximity_raw)
}

isuncovered() {
	if [ $(getproximity) -lt 20 ]; then
		echo true
	else
		echo false
	fi
}

socat -u OPEN:/dev/null UNIX-CONNECT:$MPVDIR/socket &> /dev/null
if [ "$?" = "0" ]; then
	MPVSTATE="running"
else
	MPVSTATE="closed"
fi

# sxmo_audioout.sh Speaker
# amixer sset 'Line Out' 100%
if [ "$MPVSTATE" = "closed" ]; then
	mpv --input-ipc-server=$MPVDIR/socket --loop --no-video "$RINGTONE" &
	MPVPID=$!
else
	mpvctl.sh loadfileloop "$RINGTONE"
fi

if [ "$LOCKED" = "true" ]; then
    if [ "$(isuncovered)" = "true" ]; then
        pkill sxmo_screenlock
    fi
else
    sxmo_lisgdstart.sh
fi

VOICECALLID="$(
	mmcli -m "$(modem_n)" --voice-list-calls -a |
	grep -Eo '[0-9]+ incoming \(ringing-in\)' |
	grep -Eo '[0-9]+'
)"

(
while true; do
    sxmo_vibratepine 1000
    sxmo_notificationwrite.sh \
        "$NOTIFDIR/incomingcall_${VOICECALLID}_notification" \
        "sxmo_modemcall.sh pickup $VOICECALLID" \
        none \
        "Pickup - $1" &
#    sxmo_notificationwrite.sh \
#        "$NOTIFDIR/incomingcall_${VOICECALLID}_notification_discard" \
#        "sxmo_modemcall.sh hangup $VOICECALLID" \
#        none \
#        "Discard - $1" &
    sleep 0.5
done
) &
VIBRATEPID=$!

while true; do    
#    dunstify -r 1669 $1
    incallmonitor
    if [ -n "$(pgrep sxmo_screenlock)"]; then
        if [ "$(isuncovered)" = "true" ]; then
            pkill sxmo_screenlock
        fi
    fi
done

Pickup script:


#!/usr/bin/env sh

trap gracefulexit KILL TERM INT

stopringing() {
	PID=$(ps -ef | grep sxmo/hooks/ring | grep -v grep | awk '{print $1}')
	if [[ -n "$PID" ]]; then
		kill -SIGUSR1 $PID
		kill $PID
	fi
}

unlock() {
	pkill sxmo_screenlock
}

lock() {
	sxmo_screenlock --screen-off &
}

gracefulexit() {
	stopringing
	unlock
	exit 0
}

getproximity() {
	echo $(cat /sys/bus/iio/devices/iio:device1/in_proximity_raw)
}

isuncovered() {
	if [ $(getproximity) -lt 15 ]; then
		echo true
	else
		echo false
	fi
}

audiospeakerphone() {
	[[ "$(sxmo_audiocurrentdevice.sh)" != "Line Out" ]] && sxmo_audioout.sh Speaker
	if [[ -n "$(pgrep sxmo_screenlock)" ]]; then
		LOCKED=true
	else
		LOCKED=false
	fi
	[[ "$LOCKED" == "true" ]] && unlock
}

audioearpiece() {
	[[ "$(sxmo_audiocurrentdevice.sh)" != "Earpiece" ]] && sxmo_audioout.sh Earpiece
	if [[ -n "$(pgrep sxmo_screenlock)" ]]; then
		LOCKED=true
	else
		LOCKED=false
	fi
	[[ "$LOCKED" == "false" ]] && lock
}

stopringing

TOGGLESPEAKER=false
while true; do
	if [[ "$(isuncovered)" == "true" ]]; then
		[[ "$TOGGLESPEAKER" == "true" ]] && audiospeakerphone
	else
		audioearpiece
		TOGGLESPEAKER=true
	fi
	sleep 1
done

Lisgdstart script


#!/usr/bin/env sh

if [ -z "$LISGD_THRESHOLD" ]; then
	LISGD_THRESHOLD=125
fi
if [ -z "$LISGD_THRESHOLD_PRESSED" ]; then
	LISGD_THRESHOLD_PRESSED=60
fi

modem_n() {
	MODEMS="$(mmcli -L)"
	echo "$MODEMS" | grep -oE 'Modem\/([0-9]+)' | cut -d'/' -f2
}

callmonitor() {
	CALLRINGING=$(mmcli -m "$(modem_n)" --voice-list-calls -a | grep -Eo '[0-9]+ incoming \(ringing-in\)')
	if [[ "$CALLRINGING" == "" ]]; then
		echo false
	else
		echo true
	fi
}


startnormal() {
	#-g format:
	#   fingers,swipe,edge,distance,command
	#order matters, only the first match gets executed
	lisgd "$@" -t "$LISGD_THRESHOLD" -T "$LISGD_THRESHOLD_PRESSED" \
		-g '1,DRUL,BR,*,sxmo_hotcorner.sh bottomright' \
		-g '1,DLUR,BL,*,sxmo_hotcorner.sh bottomleft' \
		-g '1,ULDR,TL,*,sxmo_hotcorner.sh topleft' \
		-g '1,URDL,TR,*,sxmo_hotcorner.sh topright' \
		-g '1,LR,B,L,sxmo_gesturehandler.sh enter' \
		-g '1,RL,B,L,sxmo_gesturehandler.sh back' \
		-g '1,LR,L,*,sxmo_gesturehandler.sh prevdesktop' \
		-g '1,RL,R,*,sxmo_gesturehandler.sh nextdesktop' \
		-g '1,DU,L,*,P,sxmo_gesturehandler.sh volup' \
		-g '1,UD,L,*,P,sxmo_gesturehandler.sh voldown' \
		-g '1,LR,T,*,P,sxmo_gesturehandler.sh brightnessup' \
		-g '1,RL,T,*,P,sxmo_gesturehandler.sh brightnessdown' \
		-g "1,DU,B,*,sxmo_gesturehandler.sh showkeyboard" \
		-g "1,UD,B,*,sxmo_gesturehandler.sh hidekeyboard" \
		-g "1,UD,T,*,sxmo_gesturehandler.sh showmenu" \
		-g "1,DU,T,*,sxmo_gesturehandler.sh hidemenu" \
		-g "2,UD,T,*,sxmo_gesturehandler.sh showsysmenu" \
		-g "2,UD,B,*,sxmo_gesturehandler.sh closewindow" \
		-g "3,UD,B,*,sxmo_gesturehandler.sh killwindow" \
		-g '2,RL,*,*,sxmo_gesturehandler.sh moveprevdesktop' \
		-g '2,LR,*,*,sxmo_gesturehandler.sh movenextdesktop' \
		-g '1,DU,R,*,P,sxmo_gesturehandler.sh scrollup_short' \
		-g '1,UD,R,*,P,sxmo_gesturehandler.sh scrolldown_short' \
		-g '1,LR,R,S,sxmo_gesturehandler.sh scrollright_short' \
		-g '1,RL,L,S,sxmo_gesturehandler.sh scrollleft_short' \
		&
}

startcall() {
	#-g format:
	#   fingers,swipe,edge,distance,command
	#order matters, only the first match gets executed
	lisgd "$@" -t "$LISGD_THRESHOLD" -T "$LISGD_THRESHOLD_PRESSED" \
		-g "2,DU,*,M,sxmo_gesturehandler.sh callpickup" \
		-g "2,UD,*,M,sxmo_gesturehandler.sh callhangup" \
		&
}

if [[ "$(callmonitor)" == "false" ]]; then
	startnormal "$@"
else
	startcall "$@"
fi

~saba 3 months ago

dinkocar, looks interesting. Can you show your changes to sxmo_gesturehandler.sh for callpickup and callhangup?

~dinkocar 3 months ago

It is implemented in gesture hook script, here it is:


#!/usr/bin/env sh
WMCLASS="$1"
ACTION="$2"

finish() {
	echo "$1">&2
	notify-send "$1"
	exit 1
}

modem_n() {
	MODEMS="$(mmcli -L)"
	echo "$MODEMS" | grep -qoE 'Modem\/([0-9]+)' || finish "Couldn't find modem - is your modem enabled?"
	echo "$MODEMS" | grep -oE 'Modem\/([0-9]+)' | cut -d'/' -f2
}

case "$ACTION" in
	"callpickup")
		VOICECALLID="$(
			mmcli -m "$(modem_n)" --voice-list-calls -a |
			grep -Eo '[0-9]+ incoming \(ringing-in\)' |
			grep -Eo '[0-9]+'
		)"
		setsid -f sh -c "sxmo_modemcall.sh pickup $VOICECALLID"
		exit 0
		;;
	"callhangup")
		VOICECALLID="$(
			mmcli -m "$(modem_n)" --voice-list-calls -a |
			grep -Eo '[0-9]+ incoming \(ringing-in\)' |
			grep -Eo '[0-9]+'
		)"
		setsid -f sh -c "sxmo_modemcall.sh hangup $VOICECALLID"
		exit 0
		;;
esac

if [ "$WMCLASS" = "st-256color" ]; then
	case "$ACTION" in
		"scrollup_short")
			xdotool key --clearmodifiers Ctrl+Shift+b
			exit 0
			;;
		"scrolldown_short")
			xdotool key --clearmodifiers Ctrl+Shift+f
			exit 0
			;;
	esac
fi
exit 1

~stacyharper 3 months ago

I really like the proximity sensor usage. We could use this logic in the screenlock binary through a new argument proximity-lock which will auto-lock screen when the phone is sticked to the ear.

The sxmo_modemdial.sh should have a root menu to pickup, hangup or mute. This script will wrap this new proximity-lock.

Our modemmonitor now have to unlock then sxmo_modemdial.sh then lock back (if locked on incoming calls).

Lets say the phone is in your pocket. You receive a call. The screen stay locked black, you take the phone in your hand, the screen unlock itself showing the Pickup, Hangup, Mute menu. You pickup then put the phone at your ear, the screen auto lock itself. When hangup, the phone go back in it previous state.

~stacyharper 3 months ago

sxmo_modemcall.sh instead of sxmo_modemdial.sh sorry

~stacyharper 3 months ago

~dinkocar 3 months ago

Actually, I was also thinking about implementing call menu in dmenu (in fact just today). And here are some ideas that I had, I don't know how feasible it is. First problem which is obvious is what if dmenu is already opened when call comes in. If you kill existing dmenu, you have to be sure that the script which has started it will behave in predictable manner, which basically means that it has to close, without doing anything. If the script is poorly written it can actually execute some action, which can then interfere with the call, or do something unexpected. So the idea that I had, which would be least intrusive, and I had inspiration in i3, which I use daily (I have dwm only on pinephone) is to open new workspace (I don't know if dwm calls it workspace, but the thing which is numbered with numbers 1,2,3,4), maybe give it the name "Call" (i3 can give names to workspaces, not only numbers) and open dmenu for call there. After call ends this new workspace is closed, as it will be empty. And user can switch between "Call" workspace and any other workspace during call, if needed. Open questions for me in this scenario are (I haven't investigated, so I don't know):

  1. can dwm open new workspace, which is not configured during compile time (can it have name or only number, this is not very important)
  2. can dmenu be opened twice (if it is already opened by user before call, you don't need to close it in this case).

So, these are just some preliminary ideas which I had, maybe they can be of some use :)

~stacyharper 3 months ago*

Actually, dmenu are not stucked to one workspace. You could browse workspaces, the dmenu will follow you.

IMHO, we should find a way to replace and enqueue dmenu when another is run

~stacyharper 3 months ago

  1. can dmenu be opened twice (if it is already opened by user before call, you don't need to close it in this case).

It is an issue I also encountered. You can't even run another menu while a windowed one is open. I don't have any good solutions atm

~stacyharper 3 months ago

This is, I expect, a last step: https://lists.sr.ht/~mil/sxmo-devel/patches/21868

~stacyharper 3 months ago

It is pretty inspired from the dinkocar hooks. It use a new smart proximity lock/unlock script around a new pickup menu. It should not change the current behavior on missed calls and put the phone back to crust after.

~dinkocar 3 months ago

I must say I am looking forward to this next release. I see a lot of work done on phone answering, sms problem with international characters is fixed (when new modemmonitor gets merged), and hardware button hooks added. It is really looking great.

But back on topic. If I got it right, when call is incoming, and screen is locked, phone will be unlocked (screen on) only when moved (picked up). But then it is missing my basic use case for incoming call, which is: phone on table, face up. Call comes in, and I just glance at it quickly without picking it up (especially if my hands are dirty) and decide weather to answer right away or call back later. I would suggest to unlock it only based on proximity sensor, and if call is not answered to put it back to sleep, crust or display only based on previous state. And you can get previous state from sxmo_screenlock command line parameter, as you are already checking for sxmo_screenlock to see if it is locked. SCREENLOCKARG=$(ps | grep sxmo_screenlock | grep -v grep | awk '{ print $5 }') Of course if call is answered, screen is not locked after the call.

~stacyharper 3 months ago

I completly agree with you that not showing the menu is a mess. Plus, it is pretty sure that the screen will not be black but showing your wallpaper without dmenu. It will depend of the screen state before crust (black or low brightness).

The thing is that we cannot actually display dmenu while screen is locked. And if we unlock it, we will not go back automaticaly in crust. We will start another fresh sxmo_lockscreen which is not aware of the old one. Cause we could go in crust not with command line parameters but with triple vol up.

But yes, I think we will fix this when we will be able to display dmenu while locked. Taking the phone in hand will unlock, and we will press Pickup and be happy.

~dinkocar 3 months ago

Interesting. I did not know that when using volume buttons sxmo_screenlock is used without command line parameters. I am using hotcorners for locking, so I always have command line parameters :) and it saves the buttons.

~kavuskazian 12 days ago

There are some really good ideas here, any plans to include any of them in 1.5.0?

~stacyharper 20 hours ago

Yes this issue stayed dangling here but this reworks are on master from some time now. Ready for next realease.

Register here or Log in to comment, or comment via email.