[GUIDE] Volume Key Selection in Flashable Zip

Search This thread

Zackptg5

Recognized Developer
Sep 18, 2014
4,086
6,680
zackptg5.com
Although Aroma installer is great, development on it stopped a while ago and many devices aren't compatible with it. However the ability for selections in an installer hasn't been completely lost. You can use the volume keys to make selections through a couple different methods.
Note that this needs put into a shell script so either you need to have the updater-script call a shell script or use a dummy updater-script and have it in the update-binary

This combines both methods of volume key selection that I've stumbled across.

The one in the choose method is by @Chainfire and is from his VerifiedBootSigner zip.

The one in the chooseold method uses the keycheck binary by someone755. The original idea was by @Zappo here which I modified a bit to not use the timeout binary since it was a bit wonky when I tested it and to work with any volume key setup. I think the keycheck binary is arm compiled but not sure.

  1. First thing that happens though is that it attempts to get the selection from the zip name. The user can add new or old to the zip (make sure there are no spaces) and skip the whole volume key thing (useful if neither vol key method works on their device - note that this won't work with tools like magisk manager which rename the zip to "install.zip" when flashing).
  2. Second is that the keytest function is run. This is by me tests the chainfire method. One of his comments is that his method needs to be tested with older versions of android and sure enough, it doesn't work properly on many. So the keytest function tests the chainfire method and checks for an error. If there is no error, the installer will use the choose (chainfire) method. If there is an error, it'll use the chooseold (keycheck) method. I favor chainfire's because it's not reliant on a 3rd part binary that may not work with x86 and other devices with unusual cpu architectures
  3. Third, the selection process is run. If using choose, the user makes their selection and the installer continues. If using chooseold, the installer will prompt the user to enter volume up, then volume down. This "programs" the vol keys for that device since it may vary between devices. Then the user makes their selection and the installer moves on.

Here's the code. At the bottom of it are 2 comments where you can put your stuff you want to have happen depending on the selection.
Code:
# Get option from zip name if applicable
case $(basename $ZIP) in
  *new*|*New*|*NEW*) NEW=true;;
  *old*|*Old*|*OLD*) NEW=false;;
esac

# Change this path to wherever the keycheck binary is located in your installer
KEYCHECK=$INSTALLER/keycheck
chmod 755 $KEYCHECK

keytest() {
  ui_print "- Vol Key Test -"
  ui_print "   Press a Vol Key:"
  (/system/bin/getevent -lc 1 2>&1 | /system/bin/grep VOLUME | /system/bin/grep " DOWN" > $INSTALLER/events) || return 1
  return 0
}   

choose() {
  #note from chainfire @xda-developers: getevent behaves weird when piped, and busybox grep likes that even less than toolbox/toybox grep
  while true; do
    /system/bin/getevent -lc 1 2>&1 | /system/bin/grep VOLUME | /system/bin/grep " DOWN" > $INSTALLER/events
    if (`cat $INSTALLER/events 2>/dev/null | /system/bin/grep VOLUME >/dev/null`); then
      break
    fi
  done
  if (`cat $INSTALLER/events 2>/dev/null | /system/bin/grep VOLUMEUP >/dev/null`); then
    return 0
  else
    return 1
  fi
}

chooseold() {
  # Calling it first time detects previous input. Calling it second time will do what we want
  $KEYCHECK
  $KEYCHECK
  SEL=$?
  if [ "$1" == "UP" ]; then
    UP=$SEL
  elif [ "$1" == "DOWN" ]; then
    DOWN=$SEL
  elif [ $SEL -eq $UP ]; then
    return 0
  elif [ $SEL -eq $DOWN ]; then
    return 1
  else
    ui_print "   Vol key not detected!"
    abort "   Use name change method in TWRP"
  fi
}
ui_print " "
if [ -z $NEW ]; then
  if keytest; then
    FUNCTION=choose
  else
    FUNCTION=chooseold
    ui_print "   ! Legacy device detected! Using old keycheck method"
    ui_print " "
    ui_print "- Vol Key Programming -"
    ui_print "   Press Vol Up Again:"
    $FUNCTION "UP"
    ui_print "   Press Vol Down"
    $FUNCTION "DOWN"
  fi
  ui_print " "
  ui_print "- Select Option -"
  ui_print "   Choose which option you want installed:"
  ui_print "   Vol Up = New, Vol Down = Old"
  if $FUNCTION; then 
    NEW=true
  else 
    NEW=false
  fi
else
  ui_print "   Option specified in zipname!"
fi

if $NEW; then
  # insert stuff for new here
else
  # insert stuff for old here
fi

Attached is the keycheck binary. The original source of it is here along with the timeout binary if you want to give that a go

If you want to have more than 2 selections, you can just add more selections by adding conditionals and calling $FUNCTION again. The V4A mod I help with here is a good example of this

If you have a device with a bixby button and want to use it or you have awk bundled in your installer and/or on target device (it's a part of busybox) and want to use an alternative getevent method, check out this post. Big thanks to @ianmacd


If you know of any other methods or of any improvements (since much of this is kind of hacky), let me know! I'll add it here :fingers-crossed:
 

Attachments

  • keycheck.zip
    84.3 KB · Views: 2,150
Last edited:

OldMid

Senior Member
Feb 5, 2018
560
786
Hey @Zackptg5, Ive been making a module that is kinda based entirely around this Volume key thing, not gonna give anything away just yet, but it requires a lot of choices to be made using the volume keys. Based on what the script above shows, the key inputs are tested for everytime you want to get an input, with the keytest function, then the choose port function is decided on that.

From the above code, for my device, the keytest would recognise the newer method and do that one the first time around, but whenever an input is required a second time, it would revert to the legacy ,ethod. Time consuming. So what I did was store tje exit status of the keytest function as a variable keytest_status, and always make a check against that variable whenever an input is needed.

For those with a modern keytest method, this would solve the function reverting to the legacy one. Check the attached file for a better description. I'm still working away so if i find anything else I'll let you know:good:
Also added a couple functions for size benefits etc

Sent from my OnePlus5T using XDA Labs
 

Attachments

  • install.sh.txt
    2.8 KB · Views: 481

Zackptg5

Recognized Developer
Sep 18, 2014
4,086
6,680
zackptg5.com
Hey @Zackptg5, Ive been making a module that is kinda based entirely around this Volume key thing, not gonna give anything away just yet, but it requires a lot of choices to be made using the volume keys. Based on what the script above shows, the key inputs are tested for everytime you want to get an input, with the keytest function, then the choose port function is decided on that.

From the above code, for my device, the keytest would recognise the newer method and do that one the first time around, but whenever an input is required a second time, it would revert to the legacy ,ethod. Time consuming. So what I did was store tje exit status of the keytest function as a variable keytest_status, and always make a check against that variable whenever an input is needed.

For those with a modern keytest method, this would solve the function reverting to the legacy one. Check the attached file for a better description. I'm still working away so if i find anything else I'll let you know:good:
Also added a couple functions for size benefits etc

Sent from my OnePlus5T using XDA Labs

Not quite sure what you mean but the keytest function is only run once when the script is initially run to determine whether the new or old choose function should be used. It also looks like you based yours on v4a (the one in the OP here has been reworked a bit to make it easier/more efficient). Also changed it up a bit to make it easier for you, let me know if this does what you want
 

OldMid

Senior Member
Feb 5, 2018
560
786
Not quite sure what you mean but the keytest function is only run once when the script is initially run to determine whether the new or old choose function should be used. It also looks like you based yours on v4a (the one in the OP here has been reworked a bit to make it easier/more efficient). Also changed it up a bit to make it easier for you, let me know if this does what you want
No attachement:laugh: What I meant was that it would to the legacy key programming function every second time an input was needed, and the normal one every first time.
It would:
Initial key programming
detect modern version and continue
if an input is required it would switch back to legacy method
switch back to modern when another input is needed
switch back to legacy again
repeat until no more inputs are needed and script is finished running. But this may also be because I'm using the old logic:silly:

Sent from my OnePlus5T using XDA Labs
 

Zackptg5

Recognized Developer
Sep 18, 2014
4,086
6,680
zackptg5.com
No attachement:laugh: What I meant was that it would to the legacy key programming function every second time an input was needed, and the normal one every first time.
It would:
Initial key programming
detect modern version and continue
if an input is required it would switch back to legacy method
switch back to modern when another input is needed
switch back to legacy again
repeat until no more inputs are needed and script is finished running. But this may also be because I'm using the old logic:silly:

Sent from my OnePlus5T using XDA Labs

Oh, that may be because of the old logic. Does that happen with the one I attached on the last post?
 

Oki

Senior Member
Jul 6, 2006
1,009
1,864
East Coast
HMMM... It doesn't work for me. I am trying to create a ZIP file to do some updates into the system requiring basic A/B selections. I am trying to implement this in a basic TWRP ZIP module. Have you managed to include it in a flashable ZIP file without Magisk? I could adapt V4A FX installer, but I don't want this to be a Unity module since it doesn't install anything. For some reason removing that unity thing is creating all the problem. Any clue?
 
  • Like
Reactions: Miustone

Zackptg5

Recognized Developer
Sep 18, 2014
4,086
6,680
zackptg5.com
HMMM... It doesn't work for me. I am trying to create a ZIP file to do some updates into the system requiring basic A/B selections. I am trying to implement this in a basic TWRP ZIP module. Have you managed to include it in a flashable ZIP file without Magisk? I could adapt V4A FX installer, but I don't want this to be a Unity module since it doesn't install anything. For some reason removing that unity thing is creating all the problem. Any clue?
I'll need to see it to find what the problem is. You can pm me if you don't want it public yet
 

Oki

Senior Member
Jul 6, 2006
1,009
1,864
East Coast
I'll need to see it to find what the problem is. You can pm me if you don't want it public yet
I solved it using only the keycheck program. getevent was not working fine for me. You can download and inspect my code here.

This is my version:

Code:
#!/sbin/sh
ui_print() {
  echo -n -e "ui_print $1\n" > /proc/self/fd/$OUTFD
  echo -n -e "ui_print\n" > /proc/self/fd/$OUTFD
}

keytest() {
  $KEYCHECK
  KEYCODE=$?
  if [ "$KEYCODE" = 42 ] ; then
    return 0
  else
    return 1
  fi
}

customkey() {
  # Calling it first time detects previous input. Calling it second time will do what we want
  $KEYCHECK
  #$KEYCHECK
  SEL=$?
  if [ "$1" == "UP" ]; then
    UP=$SEL
  elif [ "$1" == "DOWN" ]; then
    DOWN=$SEL
  elif [ $SEL -eq $UP ]; then
    return 0
  elif [ $SEL -eq $DOWN ]; then
    return 1
  else
    ui_print "   Vol key not detected!"
    abort "   Use name change method in TWRP"
  fi
}

##### THE PARTY STARTS HERE ########

# INITIAL CLEANUP
cd /tmp
rm -rf $INSTALLER 2>/dev/null
mkdir -p $INSTALLER

# extract files
ui_print "Extracting files."
cd $INSTALLER
unzip -o "$ZIP"
chmod 777 $KEYCHECK

ui_print " "
ui_print " #########################################"
ui_print " PROGRAM NAME"
ui_print " #########################################"
ui_print " "
ui_print " Welcome message"
ui_print " "
ui_print " Press Vol Up to continue..."
if keytest; then
  FUNCTION=keytest
else
  FUNCTION=customkey
  ui_print " - Device detected! but using custom key method"
  ui_print " "
  ui_print " - Vol Key Programming -"
  ui_print "   Press Vol Up Again..."
  $FUNCTION "UP"
  ui_print "   Press Vol Down..."
  $FUNCTION "DOWN"
fi

# QUESTION 1 ##########
ui_print  " - Continue?"
ui_print  "   Vol UP = YES, Vol DN = NO"
if ! $FUNCTION ; then
  ui_print  " "
  ui_print  " - Loser...."
  exit 0
fi

# QUESTION 2 ##########
ui_print  " "
ui_print  " - Do you like this script?"
ui_print  "   Vol UP: YES / Vol DN: NO"
if $FUNCTION ; then
  ui_print  " - THANKS!!!!!"
else
  ui_print  " - I'm so sorry."
fi

# MORE QUESTIONS... ##########

Thanks!
 
Last edited:

Zackptg5

Recognized Developer
Sep 18, 2014
4,086
6,680
zackptg5.com
I solved it using only the keycheck program. getevent was not working fine for me. You can download and inspect my code here.

This is my version:

Code:
#!/sbin/sh
ui_print() {
  echo -n -e "ui_print $1\n" > /proc/self/fd/$OUTFD
  echo -n -e "ui_print\n" > /proc/self/fd/$OUTFD
}

keytest() {
  $KEYCHECK
  KEYCODE=$?
  if [ "$KEYCODE" = 42 ] ; then
    return 0
  else
    return 1
  fi
}

customkey() {
  # Calling it first time detects previous input. Calling it second time will do what we want
  $KEYCHECK
  #$KEYCHECK
  SEL=$?
  if [ "$1" == "UP" ]; then
    UP=$SEL
  elif [ "$1" == "DOWN" ]; then
    DOWN=$SEL
  elif [ $SEL -eq $UP ]; then
    return 0
  elif [ $SEL -eq $DOWN ]; then
    return 1
  else
    ui_print "   Vol key not detected!"
    abort "   Use name change method in TWRP"
  fi
}

##### THE PARTY STARTS HERE ########

# INITIAL CLEANUP
cd /tmp
rm -rf $INSTALLER 2>/dev/null
mkdir -p $INSTALLER

# extract files
ui_print "Extracting files."
cd $INSTALLER
unzip -o "$ZIP"
chmod 777 $KEYCHECK

ui_print " "
ui_print " #########################################"
ui_print " PROGRAM NAME"
ui_print " #########################################"
ui_print " "
ui_print " Welcome message"
ui_print " "
ui_print " Press Vol Up to continue..."
if keytest; then
  FUNCTION=keytest
else
  FUNCTION=customkey
  ui_print " - Device detected! but using custom key method"
  ui_print " "
  ui_print " - Vol Key Programming -"
  ui_print "   Press Vol Up Again..."
  $FUNCTION "UP"
  ui_print "   Press Vol Down..."
  $FUNCTION "DOWN"
fi

# QUESTION 1 ##########
ui_print  " - Continue?"
ui_print  "   Vol UP = YES, Vol DN = NO"
if ! $FUNCTION ; then
  ui_print  " "
  ui_print  " - Loser...."
  exit 0
fi

# QUESTION 2 ##########
ui_print  " "
ui_print  " - Do you like this script?"
ui_print  "   Vol UP: YES / Vol DN: NO"
if $FUNCTION ; then
  ui_print  " - THANKS!!!!!"
else
  ui_print  " - I'm so sorry."
fi

# MORE QUESTIONS... ##########

Thanks!

I prefer the getevent one because it doesn't involve any binaries but it is more finicky than the keycheck method. Since your mod is for arm devices, keycheck should be fine. The keytest stuff all looks good except that in the keytest function, you probably would want it to be
Code:
 if [ $KEYCODE -eq 42 ]; then
since it's integer comparison. You could keep as string the way you have it but you would need a '==' rather than a '='
Also, the keytest function doesn't program volume down key at all (it's typically 21). I just always use the custom key logic just in case there's that one weird device
 

Oki

Senior Member
Jul 6, 2006
1,009
1,864
East Coast
I prefer the getevent one because it doesn't involve any binaries but it is more finicky than the keycheck method. Since your mod is for arm devices, keycheck should be fine. The keytest stuff all looks good except that in the keytest function, you probably would want it to be
Code:
 if [ $KEYCODE -eq 42 ]; then
since it's integer comparison. You could keep as string the way you have it but you would need a '==' rather than a '='
Also, the keytest function doesn't program volume down key at all (it's typically 21). I just always use the custom key logic just in case there's that one weird device
I totally agree. I don't want to load the TWRP Zip with unnecessary tools. My problem was that for some reason the getevent method was colliding with some libraries in the implementation for my device, an Axon 7. So I decided to go this way. I would like to convert it to pure getevent method.
Regarding the comparison, you are right, I will have to change that. The link is the very first working version of the tool and there is a lot of code cleanup required. The tool I have developed is a TWRP Zip module that splits a vendor partition from system or userdata, so developers could create treblerized roms for legacy devices. I have an Axon 7, released with Android M, and we have now unofficial Android P, LOS 16.0 and a couple of treble roms supporting a lot of GSI. My objective is to make it as general and compatible as I could.

Thanks Again!
 

Zackptg5

Recognized Developer
Sep 18, 2014
4,086
6,680
zackptg5.com
Actually, a single '=' is fine for string comparison, and is actually the only string comparison operator accepted by the [ and test commands of POSIX-compliant shells.
Thanks for the correction, guess a single '=' could work. However, Android shell isn't posix compliant. It's its own beast :/
 

ianmacd

Senior Member
Jan 5, 2016
2,331
3,723
Amsterdam
localhost
Thanks for the correction, guess a single '=' could work. However, Android shell isn't posix compliant. It's its own beast :/

The Android shell nowadays is mksh, and yes, you're right, it isn't terribly POSIX-compliant, even when started with -o posix.

Just be aware that the '==' comparison operator doesn't work in some shells in combination with single brackets, whereas the single '=' always will. zsh, for example:

Code:
$ zsh -c '[ x = y ]'
$ zsh -c '[ x == y ]'
zsh:1: = not found

The single '=' predates '==' by quite a margin. The double '==' is best reserved for the double bracket command: [[

Anyway, I don't want to go too far off-topic. It's just that shells are an area of particular interest to me.

Thanks for starting this thread, by the way. I now user a modified version of this code in the installer of my S9/S9+ kernel, APGK, to allow the user to interactively select certain features at install-time. The only gotcha is that I have to manually mount /system to gain access to the getevent binary.

I prefer to pipe the output through awk and output only the penultimate field:

Code:
local key=$( getevent -lqc 1  | awk '{ print $(NF-1) }' )

And since the S9/S9+ also has a Bixby button, I add a line of code to return something more legible than the raw keycode when this is pressed:

Code:
[ $key = 02bf ] && key=KEY_BIXBY

Perhaps these details will be of some use to someone.
 
Last edited:

Zackptg5

Recognized Developer
Sep 18, 2014
4,086
6,680
zackptg5.com
The Android shell nowadays is mksh, and yes, you're right, it isn't terribly POSIX-compliant, even when started with -o posix.

Just be aware that the '==' comparison operator doesn't work in some shells in combination with single brackets, whereas the single '=' always will. zsh, for example:

Code:
$ zsh -c '[ x = y ]'
$ zsh -c '[ x == y ]'
zsh:1: = not found

The single '=' predates '==' by quite a margin. The double '==' is best reserved for the double bracket command: [[

Anyway, I don't want to go too far off-topic. It's just that shells are an area of particular interest to me.

Thanks for starting this thread, by the way. I now user a modified version of this code in the installer of my S9/S9+ kernel, APGK, to allow the user to interactively select certain features at install-time. The only gotcha is that I have to manually mount /system to gain access to the getevent binary.

I prefer to pipe the output through awk and output only the penultimate field:

Code:
local key=$( getevent -lqc 1  | awk '{ print $(NF-1) }' )

And since the S9/S9+ also has a Bixby button, I add a line of code to return something more legible than the raw keycode when this is pressed:

Code:
[ $key = 02bf ] && key=KEY_BIXBY

Perhaps these details will be of some use to someone.

Good to know. I link this to the OP, thanks!
 
D

Deleted member 5437200

Guest
Sorry to revive an old thread but I need some help guys. I'm converting GSI's to flashable zips and for my custom stock rom installation, I want Xposed to be installed with Vol+ and not installed(updater-script continues) with Vol-. Also, i'll be using just the old method with keycheck. Any pointers on how I would accomplish that? Thanks much
 

Top Liked Posts

  • There are no posts matching your filters.
  • 10
    Although Aroma installer is great, development on it stopped a while ago and many devices aren't compatible with it. However the ability for selections in an installer hasn't been completely lost. You can use the volume keys to make selections through a couple different methods.
    Note that this needs put into a shell script so either you need to have the updater-script call a shell script or use a dummy updater-script and have it in the update-binary

    This combines both methods of volume key selection that I've stumbled across.

    The one in the choose method is by @Chainfire and is from his VerifiedBootSigner zip.

    The one in the chooseold method uses the keycheck binary by someone755. The original idea was by @Zappo here which I modified a bit to not use the timeout binary since it was a bit wonky when I tested it and to work with any volume key setup. I think the keycheck binary is arm compiled but not sure.

    1. First thing that happens though is that it attempts to get the selection from the zip name. The user can add new or old to the zip (make sure there are no spaces) and skip the whole volume key thing (useful if neither vol key method works on their device - note that this won't work with tools like magisk manager which rename the zip to "install.zip" when flashing).
    2. Second is that the keytest function is run. This is by me tests the chainfire method. One of his comments is that his method needs to be tested with older versions of android and sure enough, it doesn't work properly on many. So the keytest function tests the chainfire method and checks for an error. If there is no error, the installer will use the choose (chainfire) method. If there is an error, it'll use the chooseold (keycheck) method. I favor chainfire's because it's not reliant on a 3rd part binary that may not work with x86 and other devices with unusual cpu architectures
    3. Third, the selection process is run. If using choose, the user makes their selection and the installer continues. If using chooseold, the installer will prompt the user to enter volume up, then volume down. This "programs" the vol keys for that device since it may vary between devices. Then the user makes their selection and the installer moves on.

    Here's the code. At the bottom of it are 2 comments where you can put your stuff you want to have happen depending on the selection.
    Code:
    # Get option from zip name if applicable
    case $(basename $ZIP) in
      *new*|*New*|*NEW*) NEW=true;;
      *old*|*Old*|*OLD*) NEW=false;;
    esac
    
    # Change this path to wherever the keycheck binary is located in your installer
    KEYCHECK=$INSTALLER/keycheck
    chmod 755 $KEYCHECK
    
    keytest() {
      ui_print "- Vol Key Test -"
      ui_print "   Press a Vol Key:"
      (/system/bin/getevent -lc 1 2>&1 | /system/bin/grep VOLUME | /system/bin/grep " DOWN" > $INSTALLER/events) || return 1
      return 0
    }   
    
    choose() {
      #note from chainfire @xda-developers: getevent behaves weird when piped, and busybox grep likes that even less than toolbox/toybox grep
      while true; do
        /system/bin/getevent -lc 1 2>&1 | /system/bin/grep VOLUME | /system/bin/grep " DOWN" > $INSTALLER/events
        if (`cat $INSTALLER/events 2>/dev/null | /system/bin/grep VOLUME >/dev/null`); then
          break
        fi
      done
      if (`cat $INSTALLER/events 2>/dev/null | /system/bin/grep VOLUMEUP >/dev/null`); then
        return 0
      else
        return 1
      fi
    }
    
    chooseold() {
      # Calling it first time detects previous input. Calling it second time will do what we want
      $KEYCHECK
      $KEYCHECK
      SEL=$?
      if [ "$1" == "UP" ]; then
        UP=$SEL
      elif [ "$1" == "DOWN" ]; then
        DOWN=$SEL
      elif [ $SEL -eq $UP ]; then
        return 0
      elif [ $SEL -eq $DOWN ]; then
        return 1
      else
        ui_print "   Vol key not detected!"
        abort "   Use name change method in TWRP"
      fi
    }
    ui_print " "
    if [ -z $NEW ]; then
      if keytest; then
        FUNCTION=choose
      else
        FUNCTION=chooseold
        ui_print "   ! Legacy device detected! Using old keycheck method"
        ui_print " "
        ui_print "- Vol Key Programming -"
        ui_print "   Press Vol Up Again:"
        $FUNCTION "UP"
        ui_print "   Press Vol Down"
        $FUNCTION "DOWN"
      fi
      ui_print " "
      ui_print "- Select Option -"
      ui_print "   Choose which option you want installed:"
      ui_print "   Vol Up = New, Vol Down = Old"
      if $FUNCTION; then 
        NEW=true
      else 
        NEW=false
      fi
    else
      ui_print "   Option specified in zipname!"
    fi
    
    if $NEW; then
      # insert stuff for new here
    else
      # insert stuff for old here
    fi

    Attached is the keycheck binary. The original source of it is here along with the timeout binary if you want to give that a go

    If you want to have more than 2 selections, you can just add more selections by adding conditionals and calling $FUNCTION again. The V4A mod I help with here is a good example of this

    If you have a device with a bixby button and want to use it or you have awk bundled in your installer and/or on target device (it's a part of busybox) and want to use an alternative getevent method, check out this post. Big thanks to @ianmacd


    If you know of any other methods or of any improvements (since much of this is kind of hacky), let me know! I'll add it here :fingers-crossed:
    3
    Thanks for the correction, guess a single '=' could work. However, Android shell isn't posix compliant. It's its own beast :/

    The Android shell nowadays is mksh, and yes, you're right, it isn't terribly POSIX-compliant, even when started with -o posix.

    Just be aware that the '==' comparison operator doesn't work in some shells in combination with single brackets, whereas the single '=' always will. zsh, for example:

    Code:
    $ zsh -c '[ x = y ]'
    $ zsh -c '[ x == y ]'
    zsh:1: = not found

    The single '=' predates '==' by quite a margin. The double '==' is best reserved for the double bracket command: [[

    Anyway, I don't want to go too far off-topic. It's just that shells are an area of particular interest to me.

    Thanks for starting this thread, by the way. I now user a modified version of this code in the installer of my S9/S9+ kernel, APGK, to allow the user to interactively select certain features at install-time. The only gotcha is that I have to manually mount /system to gain access to the getevent binary.

    I prefer to pipe the output through awk and output only the penultimate field:

    Code:
    local key=$( getevent -lqc 1  | awk '{ print $(NF-1) }' )

    And since the S9/S9+ also has a Bixby button, I add a line of code to return something more legible than the raw keycode when this is pressed:

    Code:
    [ $key = 02bf ] && key=KEY_BIXBY

    Perhaps these details will be of some use to someone.
    1
    Sorry, forgot that xda doesn't like .sh files
    Yeah it fixes it:good:

    Sent from my OnePlus5T using XDA Labs
    1
    HMMM... It doesn't work for me. I am trying to create a ZIP file to do some updates into the system requiring basic A/B selections. I am trying to implement this in a basic TWRP ZIP module. Have you managed to include it in a flashable ZIP file without Magisk? I could adapt V4A FX installer, but I don't want this to be a Unity module since it doesn't install anything. For some reason removing that unity thing is creating all the problem. Any clue?
Our Apps
Get our official app!
The best way to access XDA on your phone
Nav Gestures
Add swipe gestures to any Android
One Handed Mode
Eases uses one hand with your phone