Config files are stored at:
/data/adb/modules/inputblocker/config/profiles/default.conf
/data/adb/modules/inputblocker/config/profiles/<package_name>.conf
enabled=1
lsposed_mode=1
# One region per line: isExclude,type,x1,y1,x2,y2,minPressure,maxDuration
0,0,0.65,0.0,1.0,1.0,0.15,300
1,2,0.88,0.92,0.06,0.08,0.0,0| Field | Values | Description |
|---|---|---|
| enabled | 0 or 1 |
Master toggle for this profile |
| lsposed_mode | 0 or 1 |
1 = LSPosed hook mode (recommended), 0 = overlay mode |
| paused | 0 or 1 |
1 = blocking suspended until explicitly resumed. Synced across all blocking services via com.inputblocker.PAUSE / com.inputblocker.RESUME broadcasts. |
| isExclude | 0 or 1 |
0 = block zone, 1 = exclude zone (hole in a block) |
| type | 0, 1, 2 |
0 = rectangle, 1 = circle, 2 = ellipse |
| x1, y1 | 0.0 – 1.0 |
Top-left corner (normalized) |
| x2, y2 | 0.0 – 1.0 |
Bottom-right corner (normalized) |
| minPressure | 0.0 – 1.0 |
Touch contact area threshold — ghosts with smaller contact patches (lower "pressure") are blocked. On capacitive screens Android's "pressure" is actually contact patch size, not physical force. |
| maxDuration | ms | Touch duration threshold — touches longer than this are blocked (0 = disabled) |
enabled=1
lsposed_mode=1
# Block the right 35%
0,0,0.65,0.0,1.0,1.0,0.15,300
# Exclude a small circle in the bottom-right (keep the power button usable)
1,1,0.90,0.92,0.05,0.05,0.0,0The auto-detection feature uses a DBSCAN-inspired clustering algorithm to identify ghost tap hotspots.
| Parameter | Default | Effect |
|---|---|---|
| eps | 0.03 |
Maximum distance (in normalized coordinates) between points in the same cluster. Smaller values = more, smaller clusters. |
| minPts | 3 |
Minimum points needed to form a cluster. Higher values ignore sparse ghost taps. |
- eps too small: Ghost taps that should be one region get split into many tiny regions
- eps too large: Separate ghost tap zones merge into one oversized block
- minPts too high: Sparse but real ghost taps get ignored
- minPts too low: Noise gets classified as ghost taps
Tip: Start with defaults (eps=0.03, minPts=3). If auto-detection produces too many small regions, increase eps to 0.05. If it misses sparse ghost taps, decrease minPts to 2.
The AdaptiveBlockingManager reads the block log (blocklog.txt) every 60 minutes and tightens region bounds when it detects ≥10 ghost taps at similar normalized coordinates.
How it works:
- Scans
blocklog.txtfor clustered ghost tap locations - For each existing block zone, checks if there's a tighter sub-region containing ≥90% of the detected ghosts
- If found, shrinks the zone to the tighter bounds
- Logs the optimization to logcat (
InputBlocker:Adaptive)
To force a re-optimization:
adb shell rm /data/adb/modules/inputblocker/config/blocklog.txt
adb shell pkill -f com.inputblocker.app # triggers service restartThe optimization never enlarges zones — it only tightens them based on actual data.
All module operations are accessible via shell for automation.
adb shell cat /data/adb/modules/inputblocker/config/profiles/default.confadb push my_config.conf /data/adb/modules/inputblocker/config/profiles/default.conf# Enable blocking
adb shell sed -i 's/enabled=0/enabled=1/' /data/adb/modules/inputblocker/config/profiles/default.conf
# Disable blocking (kill switch)
adb sh -c 'echo "1" > /data/adb/modules/inputblocker/config/kill_switch'adb shell cat /data/adb/modules/inputblocker/config/blocklog.txt | tail -50adb shell logcat -s InputBlocker:XposedHook
# Output: "Blocked touch at (0.72, 0.34) pressure=0.03"#!/system/bin/sh
# Quick-check ghost tap count
BLOCKLOG="/data/adb/modules/inputblocker/config/blocklog.txt"
COUNT=$(wc -l < "$BLOCKLOG")
echo "Ghost taps blocked since last reset: $COUNT"The crash detection system operates across three layers:
-
In-hook detection — Every
beforeHookedMethodis wrapped in try/catch. On exception:- Logs the error to logcat
- Calls
InputBlockerServiceManager.reportCrash(Throwable)which writes the full stack trace to/data/local/tmp/inputblocker/crash_logs/<timestamp>.log - Increments the crash counter at
/data/local/tmp/inputblocker/crash_count - Re-throws so the system doesn't notice
-
Boot-time detection — The
ServiceManagerreadscrash_detectedon startup:- If flag exists: enters safe mode (all blocking disabled, overlay shows "SAFE MODE")
- If flag absent: normal operation
-
3-strike safe mode — On each boot, the crash counter at
/data/local/tmp/inputblocker/crash_countis checked:- If count >= 3: enters safe mode automatically, regardless of other flags
- Counter resets on clean shutdown
- Prevents repeated crash loops from locking the device
The companion app includes CrashLogActivity for viewing crash reports directly on the device:
- Open the InputBlocker companion app
- Tap Quick Actions in the menu
- Select View Crash Logs
- Each entry shows timestamp, error message, and full stack trace
Crash logs are stored at /data/local/tmp/inputblocker/crash_logs/ and persist across reboots.
# List available crash logs
adb shell ls -la /data/local/tmp/inputblocker/crash_logs/
# Read a specific crash log
adb shell cat /data/local/tmp/inputblocker/crash_logs/crash_20260101_120000.log
# Check crash count
adb shell cat /data/local/tmp/inputblocker/crash_count
# Reset crash counter (after investigating)
adb shell echo "0" > /data/local/tmp/inputblocker/crash_countadb shell rm /data/adb/modules/inputblocker/config/crash_detected
adb shell echo "0" > /data/local/tmp/inputblocker/crash_count
adb rebootOr just clear it from the companion app's settings screen.
The companion app reloads configuration changes in real time without requiring a service restart. This is powered by ConfigFileObserver, a two-layer file monitoring system:
Config File Change → FileObserver (inotify)
→ On failure/unsupported FS → 2s polling fallback
→ Config reloaded in memory
→ Services pick up new region definitions
- Primary layer:
FileObserveruses Linux inotify to receive instant notifications when config files change, are created, or are deleted. - Fallback layer: On filesystems that don't support inotify (certain FUSE mounts, some MTP or virtual storage), a polling loop checks file modification timestamps every 2 seconds.
- Scope: Monitors all
.conffiles in the profiles directory, pluskill_switch,crash_detected, andpausedstate changes.
- Editing
default.confor any per-app profile via ADB or PC Designer - Creating or deleting a profile file
- Writing
paused=1orpaused=0to the config - Creating or removing the
kill_switchfile - Crash flag changes
When a change is detected, the relevant service (OverlayService, AccessibilityService, or hook module) reloads its region definitions from disk. No service restart required.
# Watch for reload events in logcat
adb shell logcat -s InputBlocker:ConfigFileObserver
# Expected output:
# "Config file modified: /data/adb/modules/inputblocker/config/profiles/default.conf"
# "Reloaded 3 regions from config"The companion app provides a pause/resume mechanism that temporarily suspends all blocking without disabling the profile. This is useful for scenarios where you need full touch access temporarily.
| Method | Steps |
|---|---|
| Quick Actions toggle | Open companion app → Quick Actions → tap Pause |
| Notification buttons | Pull down notification → tap Pause 5min or Pause 30min |
| Shell command | adb shell am broadcast -a com.inputblocker.PAUSE |
| Method | Steps |
|---|---|
| Quick Actions toggle | Open companion app → Quick Actions → tap Resume |
| Notification buttons | Pull down notification → tap Resume |
| Auto-resume | Timer expires and re-enables blocking automatically |
| Shell command | adb shell am broadcast -a com.inputblocker.RESUME |
- The MainActivity toggle (or notification action) broadcasts
com.inputblocker.PAUSEorcom.inputblocker.RESUMEas an Android intent. - All three blocking services listen for these intents:
- OverlayService — stops blocking touches in the overlay
- AccessibilityService — stops blocking via accessibility gesture interception
- LSPosed hook — reads
paused=1from the config file and stops filtering at the input dispatcher level
- The
paused=1flag is written to the config file, so pause state persists across service restarts and reboots. - Each service runs an auto-resume timer. When the selected pause duration (5 min, 30 min) expires, blocking is re-enabled automatically.
The persistent notification includes three action buttons:
- Pause 5min — Suspends blocking for 5 minutes, then auto-resumes
- Pause 30min — Suspends blocking for 30 minutes, then auto-resumes
- Resume — Immediately re-enables blocking (only shown when paused)
These buttons work with all three services, not just the foreground service that posted the notification.
#!/system/bin/sh
# Pause blocking for a custom duration (in milliseconds)
am broadcast -a com.inputblocker.PAUSE
sleep 300 # 5 minutes
am broadcast -a com.inputblocker.RESUME
# Check current pause state
grep "^paused=" /data/adb/modules/inputblocker/config/profiles/default.confThe VolumeButtonListenerService handles emergency gesture detection. By default, it uses:
Volume Down × 3 → Volume Up × 3
The gesture sequence and timing are configurable at:
/data/adb/modules/inputblocker/config/gesture.conf
sequence=KEYCODE_VOLUME_DOWN,KEYCODE_VOLUME_DOWN,KEYCODE_VOLUME_DOWN,KEYCODE_VOLUME_UP,KEYCODE_VOLUME_UP,KEYCODE_VOLUME_UP
timeout_ms=3000sequence: Comma-separated list of keycodestimeout_ms: Max time to complete the sequence
Presets (.ibpreset files) are JSON with metadata:
{
"version": 1,
"device_model": "Pixel 6",
"config_version": "0.1.0",
"block_count": 12,
"regions": [
{"isExclude": false, "type": 0, "x1": 0.65, "y1": 0.0, "x2": 1.0, "y2": 1.0, "minPressure": 0.15, "maxDuration": 300}
]
}To share a preset:
- In companion app: Export → name your preset
- File saved to
/storage/emulated/0/InputBlocker/presets/<name>.ibpreset - Share the file — normalized coordinates make it cross-device
To measure the hook's overhead:
# Enable performance logging
adb shell setprop persist.inputblocker.perf_log 1
# Check latency log
adb shell cat /data/adb/modules/inputblocker/config/latency.log
# Each entry shows: timestamp,dispatch_us,hook_us
# dispatch_us: total dispatch time
# hook_us: time spent in InputBlocker filterExpected overhead: < 50µs per touch event. If you see > 200µs, check for excessive logging or many overlapping regions.