223 lines
7.3 KiB
Bash
Executable File
223 lines
7.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# CamSwapper HAL Hook - Integration Testing Script
|
|
# Tests the system-wide camera HAL hook installation and functionality
|
|
# Usage: ./test_hal_wrapper.sh [DEVICE_SERIAL]
|
|
#
|
|
# Prerequisites:
|
|
# - adb installed and in PATH
|
|
# - Device connected via USB (or specify serial with argument)
|
|
# - Device rooted with Magisk or KernelSU
|
|
# - Root module installed (root-module/ pushed to /data/adb/modules/camera2magic/)
|
|
# - Device rebooted after module installation
|
|
|
|
set -euo pipefail
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Test results
|
|
PASS_COUNT=0
|
|
FAIL_COUNT=0
|
|
RESULTS_LOG="test_results.log"
|
|
|
|
# ADB setup
|
|
ADB="adb"
|
|
if [ -n "${1:-}" ]; then
|
|
ADB="adb -s $1"
|
|
fi
|
|
|
|
log() {
|
|
echo -e "$*"
|
|
echo -e "$*" >> "$RESULTS_LOG"
|
|
}
|
|
|
|
pass() {
|
|
log "${GREEN}[PASS]${NC} $*"
|
|
((PASS_COUNT++))
|
|
}
|
|
|
|
fail() {
|
|
log "${RED}[FAIL]${NC} $*"
|
|
((FAIL_COUNT++))
|
|
}
|
|
|
|
warn() {
|
|
log "${YELLOW}[WARN]${NC} $*"
|
|
}
|
|
|
|
# Initialize results log
|
|
echo "CamSwapper HAL Hook - Integration Test Results" > "$RESULTS_LOG"
|
|
echo "Date: $(date)" >> "$RESULTS_LOG"
|
|
echo "=========================================" >> "$RESULTS_LOG"
|
|
|
|
log "========================================="
|
|
log "CamSwapper HAL Hook - Integration Test"
|
|
log "========================================="
|
|
log ""
|
|
|
|
# Test 0: Device connectivity
|
|
log "--- Test 0: Device Connectivity ---"
|
|
if $ADB shell "echo connected" >/dev/null 2>&1; then
|
|
pass "Device connected via adb"
|
|
else
|
|
fail "Device not connected. Check USB connection and adb authorization."
|
|
log "Cannot continue without device connection."
|
|
exit 1
|
|
fi
|
|
|
|
# Test 1: Root access
|
|
log ""
|
|
log "--- Test 1: Root Access ---"
|
|
ROOT_CHECK=$($ADB shell "su -c id" 2>/dev/null || true)
|
|
if echo "$ROOT_CHECK" | grep -q "uid=0"; then
|
|
pass "Root access available"
|
|
else
|
|
fail "Root access not available. Device must be rooted with Magisk or KernelSU."
|
|
log "Cannot continue without root."
|
|
exit 1
|
|
fi
|
|
|
|
# Test 2: Module installed
|
|
log ""
|
|
log "--- Test 2: Root Module Installation ---"
|
|
MODULE_DIR=$($ADB shell "su -c 'ls -d /data/adb/modules/camera2magic 2>/dev/null || ls -d /data/adb/modules/*camera* 2>/dev/null'" 2>/dev/null | tr -d '\r' || true)
|
|
if [ -n "$MODULE_DIR" ]; then
|
|
pass "Module directory found: $MODULE_DIR"
|
|
|
|
# Check hook library
|
|
HOOK_LIB=$($ADB shell "su -c 'ls $MODULE_DIR/libcamera_hook.so 2>/dev/null'" 2>/dev/null | tr -d '\r' || true)
|
|
if [ -n "$HOOK_LIB" ]; then
|
|
pass "libcamera_hook.so present in module"
|
|
else
|
|
fail "libcamera_hook.so NOT found in module directory"
|
|
fi
|
|
|
|
# Check sepolicy.rule
|
|
SEPOLICY=$($ADB shell "su -c 'ls $MODULE_DIR/sepolicy.rule 2>/dev/null'" 2>/dev/null | tr -d '\r' || true)
|
|
if [ -n "$SEPOLICY" ]; then
|
|
pass "sepolicy.rule present in module"
|
|
else
|
|
warn "sepolicy.rule not found (may not be required on all devices)"
|
|
fi
|
|
else
|
|
fail "Module directory not found in /data/adb/modules/"
|
|
warn "Install the module: adb push root-module/ /data/adb/modules/camera2magic/"
|
|
fi
|
|
|
|
# Test 3: Wrap property set
|
|
log ""
|
|
log "--- Test 3: Wrap Property Configuration ---"
|
|
WRAP_PROP=$($ADB shell "getprop wrap.android.hardware.camera.provider@2.7-service-google" 2>/dev/null | tr -d '\r' || true)
|
|
if echo "$WRAP_PROP" | grep -q "LD_PRELOAD"; then
|
|
pass "Wrap property set: $WRAP_PROP"
|
|
else
|
|
fail "Wrap property NOT set or empty"
|
|
warn "Expected: LD_PRELOAD=/data/adb/modules/.../libcamera_hook.so"
|
|
warn "Try: adb shell setprop wrap.android.hardware.camera.provider@2.7-service-google 'LD_PRELOAD=/data/adb/modules/camera2magic/libcamera_hook.so'"
|
|
fi
|
|
|
|
# Test 4: Config file
|
|
log ""
|
|
log "--- Test 4: Configuration File ---"
|
|
CONFIG=$($ADB shell "su -c 'cat /data/local/camera_magic/config.txt 2>/dev/null'" 2>/dev/null | tr -d '\r' || true)
|
|
if [ -n "$CONFIG" ]; then
|
|
pass "Config file exists"
|
|
log " Contents: $CONFIG"
|
|
else
|
|
warn "Config file not found at /data/local/camera_magic/config.txt"
|
|
warn "Creating default config..."
|
|
$ADB shell "su -c 'mkdir -p /data/local/camera_magic && echo \"enabled=0\" > /data/local/camera_magic/config.txt && chmod 644 /data/local/camera_magic/config.txt'" 2>/dev/null || true
|
|
pass "Default config created"
|
|
fi
|
|
|
|
# Test 5: Camera provider process detection
|
|
log ""
|
|
log "--- Test 5: Camera Provider Process ---"
|
|
PROVIDER_PID=$($ADB shell "pidof android.hardware.camera.provider@2.7-service-google" 2>/dev/null | tr -d '\r' || true)
|
|
if [ -n "$PROVIDER_PID" ]; then
|
|
pass "Camera provider process running (PID: $PROVIDER_PID)"
|
|
|
|
# Check if hook library is loaded
|
|
LOADED_LIBS=$($ADB shell "su -c 'cat /proc/$PROVIDER_PID/maps 2>/dev/null | grep libcamera_hook'" 2>/dev/null | tr -d '\r' || true)
|
|
if [ -n "$LOADED_LIBS" ]; then
|
|
pass "libcamera_hook.so loaded in camera provider process"
|
|
else
|
|
warn "libcamera_hook.so NOT detected in camera provider process maps"
|
|
warn "This may be normal if the provider hasn't been restarted since module install"
|
|
warn "Try rebooting the device or restarting the camera provider"
|
|
fi
|
|
else
|
|
warn "Camera provider process not found (may not be running yet)"
|
|
warn "The provider starts on-demand when a camera app is opened"
|
|
fi
|
|
|
|
# Test 6: SELinux status
|
|
log ""
|
|
log "--- Test 6: SELinux Status ---"
|
|
SELINUX_STATUS=$($ADB shell "getenforce" 2>/dev/null | tr -d '\r' || true)
|
|
if [ "$SELINUX_STATUS" = "Enforcing" ]; then
|
|
pass "SELinux is Enforcing (policy rules are active)"
|
|
elif [ "$SELINUX_STATUS" = "Permissive" ]; then
|
|
warn "SELinux is Permissive (policy rules not enforced, but hook should still work)"
|
|
else
|
|
warn "SELinux status unknown: $SELINUX_STATUS"
|
|
fi
|
|
|
|
# Test 7: AVC denials check
|
|
log ""
|
|
log "--- Test 7: SELinux AVC Denials ---"
|
|
AVC_DENIALS=$($ADB shell "su -c 'dmesg | grep \"avc: denied\" | grep -i camera | tail -5'" 2>/dev/null | tr -d '\r' || true)
|
|
if [ -z "$AVC_DENIALS" ]; then
|
|
pass "No camera-related AVC denials found"
|
|
else
|
|
warn "AVC denials detected (may need additional SELinux rules):"
|
|
log "$AVC_DENIALS"
|
|
fi
|
|
|
|
# Test 8: Logcat hook initialization
|
|
log ""
|
|
log "--- Test 8: Hook Initialization Logs ---"
|
|
HOOK_LOGS=$($ADB logcat -d -s CameraHook 2>/dev/null | grep -i "hook\|init\|loaded\|CameraHook" | tail -5 || true)
|
|
if [ -n "$HOOK_LOGS" ]; then
|
|
pass "Hook initialization logs found"
|
|
log "$HOOK_LOGS"
|
|
else
|
|
warn "No hook initialization logs found"
|
|
warn "This may be normal if the camera provider hasn't been restarted"
|
|
fi
|
|
|
|
# Summary
|
|
log ""
|
|
log "========================================="
|
|
log "Test Summary"
|
|
log "========================================="
|
|
log "${GREEN}Passed: $PASS_COUNT${NC}"
|
|
log "${RED}Failed: $FAIL_COUNT${NC}"
|
|
log ""
|
|
|
|
if [ "$FAIL_COUNT" -eq 0 ]; then
|
|
log "${GREEN}All tests passed!${NC}"
|
|
log ""
|
|
log "Next steps:"
|
|
log "1. Enable HAL mode in CamSwapper app"
|
|
log "2. Set video path or RTSP URL in config"
|
|
log "3. Open any camera app to verify virtual feed"
|
|
log "4. Check: adb logcat -s CameraHook for frame injection logs"
|
|
else
|
|
log "${RED}Some tests failed. Review the output above.${NC}"
|
|
log ""
|
|
log "Common fixes:"
|
|
log "- Reboot device after module installation"
|
|
log "- Verify module is in /data/adb/modules/camera2magic/"
|
|
log "- Check wrap property is set correctly"
|
|
log "- Ensure SELinux policy rules are loaded"
|
|
fi
|
|
|
|
log ""
|
|
log "Full results saved to: $RESULTS_LOG"
|
|
|
|
exit "$FAIL_COUNT"
|