Android Software Reverse Engineering & Decompilation

Automating Android Customization: Building Parametric Magisk Modules with User Input

Google AdSense Native Placement - Horizontal Top-Post banner

Introduction: The Evolution of Android Customization

Android’s open nature has always fostered a vibrant customization community. From custom ROMs to Xposed modules, users have sought ways to tailor their devices beyond stock limitations. Magisk revolutionized this by offering a “systemless” approach, allowing modifications without altering the /system partition itself. While basic Magisk modules provide static changes, the true power lies in creating parametric modules that can adapt based on user input during installation. This article will guide you through building expert-level Magisk modules that interact with the user, enabling dynamic and highly personalized systemless modifications.

Magisk Module Fundamentals: A Brief Refresher

Before diving into user input, let’s quickly recap the essential components of a Magisk module. Every module typically consists of:

  • module.prop: Contains metadata like module ID, name, author, and description.
  • customize.sh: The core script that executes during module installation, performing modifications.
  • system/: An optional directory containing files that will be overlaid onto the system partition (e.g., replacing apps, libraries).
  • post-fs-data.sh / service.sh: Optional scripts for executing commands at specific boot stages.

Our focus for user interaction will primarily be on extending the capabilities of the module’s installation process, specifically through a pre-execution script called config.sh.

The Power of config.sh: Engaging with the User

The config.sh script is executed *before* customize.sh, making it the ideal place to gather user preferences. Magisk provides a set of utility functions, sourced from util_functions.sh, that facilitate user interaction. Key functions include:

  • ui_print <message>: Displays a message to the user during installation.
  • ui_input <prompt>: Prompts the user for input and returns it. This is usually combined with read or assigned to a variable.
  • abort <message>: Halts the installation with an error message.

Let’s illustrate with a simple example: asking the user to confirm an action.

#!/system/bin/sh# This script is sourced by Magisk during installation. It runs before customize.sh.# Import utility functions from Magisk's common script.OUTFD=$1# Functions from util_functions.sh are automatically available.ui_print ""ui_print "-------------------------------------------"ui_print "       Parametric Module Installer       "ui_print "-------------------------------------------"ui_print ""ui_print "This module modifies system DPI."ui_print ""ui_print "Do you want to proceed with DPI modification? (y/n)"read -p "" CONFIRMATIONif [ "$(echo "$CONFIRMATION" | tr '[:upper:]' '[:lower:]')" != "y" ]; then  ui_print "Installation aborted by user."  abort "User chose not to proceed."fiui_print ""ui_print "Proceeding with configuration..."# We can export variables here to be accessible in customize.shexport CUSTOM_DPI="default"export ENABLE_FEATURE_X="no"

Implementing User Input for Dynamic Customization

Now, let’s build a more complex scenario: a module that allows users to set a custom DPI and enable an experimental system feature, both based on their input. This will involve reading user input in config.sh and then using those values in customize.sh to modify system properties.

Step 1: The config.sh Script

We’ll prompt for a DPI value and a yes/no for an experimental feature.

#!/system/bin/shOUTFD=$1# Basic module info and confirmationui_print ""ui_print "-------------------------------------------"ui_print "       Dynamic System Tweaker Module       "ui_print "-------------------------------------------"ui_print ""ui_print "This module allows dynamic DPI adjustment and"ui_print "enabling an experimental system feature."ui_print ""ui_print "Proceed with customization? (y/n)"read -p "" PROCEEDif [ "$(echo "$PROCEED" | tr '[:upper:]' '[:lower:]')" != "y" ]; then  ui_print "Installation aborted."  abort "User chose to abort."fiui_print ""# Prompt for DPI valueui_print "Enter desired screen DPI (e.g., 480, 520, 640):"ui_print "(Leave empty for default/no change)"read -p "" USER_DPI# Validate DPI inputif [ -n "$USER_DPI" ]; then  if ! [[ "$USER_DPI" =~ ^[0-9]+$ ]] || [ "$USER_DPI" -lt 1 ]; then    ui_print "Invalid DPI value. Please enter a positive number."    abort "Invalid DPI."  fielse  USER_DPI="" # No changeendui_print ""# Prompt for experimental featureui_print "Enable experimental feature X? (y/n)"read -p "" FEATURE_X_CHOICEif [ "$(echo "$FEATURE_X_CHOICE" | tr '[:upper:]' '[:lower:]')" = "y" ]; then  ENABLE_FEATURE_X="true"else  ENABLE_FEATURE_X="false"fi# Export variables to be used in customize.shexport MODULE_CUSTOM_DPI="$USER_DPI"export MODULE_ENABLE_FEATURE_X="$ENABLE_FEATURE_X"ui_print "Configuration complete. Proceeding to apply changes..."

Step 2: The customize.sh Script

In customize.sh, we access the exported variables and apply the modifications. We’ll target /system/build.prop, a common file for system-wide property changes.

#!/system/bin/sh# This script is sourced by Magisk during installation.# It runs after config.sh.# Magisk provides the 'magisk' binary for various tasks like 'resetprop'# and the 'util_functions.sh' functions are also available.OUTFD=$1# Helper function to modify or add properties in build.propadd_or_update_prop() {  local prop_name="$1"  local prop_value="$2"  local build_prop_file="$MODPATH/system/build.prop"  # Create build.prop in MODPATH if it doesn't exist  if [ ! -f "$build_prop_file" ]; then    touch "$build_prop_file"  fi  # Check if property exists. If so, update it. Else, add it.  if grep -q "^$prop_name=" "$build_prop_file"; then    sed -i "s|^$prop_name=.*|$prop_name=$prop_value|" "$build_prop_file"  else    echo "$prop_name=$prop_value" >> "$build_prop_file"  fi}ui_print ""ui_print "Applying customizations based on user input:"# Apply DPI change if specifiedif [ -n "$MODULE_CUSTOM_DPI" ]; then  ui_print "- Setting ro.sf.lcd_density to $MODULE_CUSTOM_DPI"  add_or_update_prop "ro.sf.lcd_density" "$MODULE_CUSTOM_DPI"else  ui_print "- DPI not changed (user specified default)"fi# Apply experimental feature if enabledif [ "$MODULE_ENABLE_FEATURE_X" = "true" ]; then  ui_print "- Enabling experimental feature X (via system prop)"  add_or_update_prop "persist.sys.feature_x.enabled" "1"  # Example of setting an additional property if needed  add_or_update_prop "sys.feature_x.value" "some_value"else  ui_print "- Experimental feature X not enabled"  # If we wanted to ensure it's off, we could add:  # add_or_update_prop "persist.sys.feature_x.enabled" "0"fiui_print ""ui_print "Customization complete! Reboot required."

In this customize.sh, we create or modify a build.prop file within our module’s system/ directory. Magisk’s systemless overlay mechanism will then ensure these properties are applied at boot without touching the original /system/build.prop. Notice the use of $MODPATH/system/build.prop. This ensures we are modifying the module’s own file, which Magisk will then overlay.

Advanced User Interaction and Module Logic

The concepts demonstrated can be expanded significantly:

  • Multiple Choice Questions:

    Use a loop and `read` to present options until valid input is received.

    # In config.shui_print ""ui_print "Choose a display mode:"ui_print "1) Standard (balanced)"ui_print "2) Vivid (saturated colors)"ui_print "3) Neutral (accurate colors)"while true; do  read -p "Enter your choice (1-3): " DISPLAY_CHOICE  case "$DISPLAY_CHOICE" in    1)  export DISPLAY_MODE="standard"; break ;;    2)  export DISPLAY_MODE="vivid"; break ;;    3)  export DISPLAY_MODE="neutral"; break ;;    *)  ui_print "Invalid choice, please try again." ;;  esacdoneui_print "Selected display mode: $DISPLAY_MODE"
  • Input Validation:

    Beyond simple numeric checks, use `grep` with regular expressions for more complex pattern matching (e.g., validating IP addresses, file paths). This ensures robust modules that don’t break due to unexpected user input.

  • Conditional File Operations:

    Based on user choices, `customize.sh` can selectively copy, delete, or modify different files. For example, installing different versions of a library (`.so` file) or injecting specific XML configurations into an app’s resources (`res` directory).

    # In customize.shif [ "$MODULE_INSTALL_AUDIO_DRIVER" = "true" ]; then  ui_print "- Installing custom audio driver..."  cp -f "$MODPATH/audio_drivers/driver_v2.so" "$MODPATH/system/lib64/libaudio_effect.so"  set_perm "$MODPATH/system/lib64/libaudio_effect.so" 0 0 0644fi

Best Practices and Debugging

  • Clear UI Prompts:

    Always provide clear instructions and examples for user input. Explain the implications of their choices.

  • Robust Validation:

    Anticipate invalid input and handle it gracefully, either by re-prompting or aborting with an informative message.

  • Modularity:

    For very complex modules, consider breaking down `customize.sh` into smaller, sourced scripts based on functionality (e.g., `install_dpi.sh`, `install_featurex.sh`) to improve readability and maintainability.

  • Logging:

    Use `ui_print` extensively to inform the user about the installation progress and the actions being taken. For advanced debugging, you can redirect output to a file: `(your_commands_here) >> $MODPATH/install.log 2>&1`.

  • Testing:

    Always test your modules on a virtual device (e.g., Android Emulator, Genymotion) or a secondary physical device before deploying to your primary phone. This is crucial for verifying the logic and preventing bootloops.

Conclusion

Parametric Magisk modules with user input elevate Android customization from static changes to dynamic, intelligent modifications. By leveraging `config.sh` and the utility functions provided by Magisk, developers can craft highly personalized modules that adapt to individual user preferences during installation. This approach not only makes modules more versatile but also empowers users with greater control over their device’s behavior without requiring advanced technical knowledge for each tweak. Master these techniques, and you’ll unlock a new realm of possibilities for systemless Android customization.

Android Mobile Specs & Compare Directory

Are you researching mobile hardware properties, processor SoCs, GPU chipsets, or RAM configurations? Access our complete specs catalog to compare up to 5 devices side-by-side!

Compare Devices Specs →
Google AdSense Inline Placement - Content Footer banner