FORUMS

[GUIDE] Volume Key Selection in Flashable Zip

3,974 posts
Thanks Meter: 6,586
 
Post Reply Email Thread
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
Attached Files
File Type: zip keycheck.zip - [Click for QR Code] (84.3 KB, 1874 views)
The Following 10 Users Say Thank You to Zackptg5 For This Useful Post: [ View ]
8th April 2018, 07:10 AM |#2  
OldMid's Avatar
Senior Member
Thanks Meter: 788
 
Donate to Me
More
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
Also added a couple functions for size benefits etc

Sent from my OnePlus5T using XDA Labs
Attached Files
File Type: txt install.sh.txt - [Click for QR Code] (2.8 KB, 410 views)
8th April 2018, 04:44 PM |#3  
Zackptg5's Avatar
OP Recognized Developer
Thanks Meter: 6,586
 
Donate to Me
More
Quote:
Originally Posted by OldMid

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
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
8th April 2018, 05:50 PM |#4  
OldMid's Avatar
Senior Member
Thanks Meter: 788
 
Donate to Me
More
Quote:
Originally Posted by Zackptg5

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 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

Sent from my OnePlus5T using XDA Labs
8th April 2018, 05:53 PM |#5  
Zackptg5's Avatar
OP Recognized Developer
Thanks Meter: 6,586
 
Donate to Me
More
Quote:
Originally Posted by OldMid

No attachement 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

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?
8th April 2018, 07:21 PM |#6  
OldMid's Avatar
Senior Member
Thanks Meter: 788
 
Donate to Me
More
Quote:
Originally Posted by Zackptg5

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

I don't see anything attached

Sent from my OnePlus5T using XDA Labs
8th April 2018, 07:28 PM |#7  
Zackptg5's Avatar
OP Recognized Developer
Thanks Meter: 6,586
 
Donate to Me
More
Quote:
Originally Posted by OldMid

I don't see anything attached

Sent from my OnePlus5T using XDA Labs

Sorry, forgot that xda doesn't like .sh files
Attached Files
File Type: txt install.sh.txt - [Click for QR Code] (2.4 KB, 190 views)
8th April 2018, 10:04 PM |#8  
OldMid's Avatar
Senior Member
Thanks Meter: 788
 
Donate to Me
More
Quote:
Originally Posted by Zackptg5

Sorry, forgot that xda doesn't like .sh files

Yeah it fixes it

Sent from my OnePlus5T using XDA Labs
The Following User Says Thank You to OldMid For This Useful Post: [ View ] Gift OldMid Ad-Free
19th August 2018, 05:35 AM |#9  
Oki's Avatar
Senior Member
Flag East Coast
Thanks Meter: 1,860
 
Donate to Me
More
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?
The Following User Says Thank You to Oki For This Useful Post: [ View ] Gift Oki Ad-Free
19th August 2018, 02:43 PM |#10  
Zackptg5's Avatar
OP Recognized Developer
Thanks Meter: 6,586
 
Donate to Me
More
Quote:
Originally Posted by Oki

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
19th August 2018, 11:56 PM |#11  
Oki's Avatar
Senior Member
Flag East Coast
Thanks Meter: 1,860
 
Donate to Me
More
Quote:
Originally Posted by Zackptg5

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!
Post Reply Subscribe to Thread

Guest Quick Reply (no urls or BBcode)
Message:
Previous Thread Next Thread
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes