Skip to content

jollySleeper/Antomate

Repository files navigation

Antomate

A lightweight Android app that automatically manages network connections based on your network type (mobile data vs WiFi).

Now supports TWO automation modes:

  • 🦊 Tailscale VPN - Automatic VPN connection management
  • 🔒 Private DNS - Automatic DNS-over-TLS configuration (NEW!)

Features

  • 🔄 Dual Automation Modes: Choose between Tailscale VPN or Private DNS
  • Private DNS Mode: Instant DNS switching without app interruption
  • 🦊 Tailscale Mode: Automatic VPN connection management
  • ⏱️ Smart Debouncing: Prevents spam operations within 30-second windows
  • 🔧 Manual Controls: Test connections manually with dedicated buttons
  • 📱 Foreground Service: Reliable background operation with persistent notification
  • 🔄 Auto-restart: Survives device reboots when automation is enabled
  • 🎨 Modern UI: Clean Compose interface with status indicators and mode selector
  • 🖼️ Edge-to-Edge Display: Full-screen immersive UI following Android 15 guidelines

Requirements

Tailscale Mode:

  • Android: API 24+ (Android 7.0+)
  • Tailscale App: Must be installed and configured
  • Permissions: Network state, WiFi state, foreground service, boot completed

Private DNS Mode:

  • Android: API 29+ (Android 10.0+)
  • ADB Access: One-time permission grant via ADB
  • Permissions: Network state, WiFi state, foreground service, boot completed, WRITE_SECURE_SETTINGS

Installation & Setup

1. Install Android Development Tools

# Install Java (if not already installed)
brew install openjdk@17

# Install Android SDK tools
brew install android-commandlinetools android-platform-tools

# Set up environment (add to ~/.zshrc)
export ANDROID_HOME=/opt/homebrew/share/android-commandlinetools
export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools
export PATH="/opt/homebrew/opt/gradle@8/bin:$PATH"

# Accept SDK licenses
yes | sdkmanager --licenses

# Install required SDK components
sdkmanager "platform-tools" "platforms;android-34" "build-tools;33.0.2"

2. Build the App

./gradlew assembleDebug

3. Install on Device

Connect your Android device with USB debugging enabled, then:

# Find your device
adb devices

# Install the APK
adb install app/build/outputs/apk/debug/app-debug.apk

Usage

Choose Your Mode

Option 1: Tailscale VPN Mode (Default)

  1. Install Tailscale: Make sure Tailscale app is installed and logged in
  2. Launch App: Open "Antomate"
  3. Select Mode: Choose "Tailscale" in the Automation Mode card
  4. Enable Automation: Toggle "Enable Automation" switch
  5. Grant Permissions: Allow network and notification permissions
  6. Monitor Status: Watch the status indicators

How it works:

  • Mobile Data → Connect: Sends CONNECT_VPN broadcast to Tailscale
  • WiFi → Disconnect: Sends DISCONNECT_VPN broadcast to Tailscale
  • User Experience: Brief 2.5s app switch, returns to previous app automatically

Option 2: Private DNS Mode (NEW!)

  1. Grant ADB Permission (one-time setup):

    adb shell pm grant io.github.jollysleeper.antomate android.permission.WRITE_SECURE_SETTINGS
  2. Configure DNS:

    • Launch "Antomate"
    • Select "Private DNS" in Automation Mode card
    • Enter your DNS hostname (e.g., dns.adguard.com, dns.google)
    • Tap "Save DNS Hostname"
  3. Enable Automation: Toggle "Enable Automation" switch

  4. Enjoy: DNS switches instantly without any app interruption!

How it works:

  • Mobile Data → Enable DNS: Configures Private DNS with your hostname
  • WiFi → Disable DNS: Turns off Private DNS
  • User Experience: Instant, no visible interruption

📖 See PRIVATE_DNS_SETUP.md for detailed setup guide

Manual Testing

Tailscale Mode:

  • Connect Now: Manually trigger VPN connection
  • Disconnect Now: Manually trigger VPN disconnection
  • Open Tailscale: Launch Tailscale app directly

Private DNS Mode:

  • Enable DNS: Manually enable Private DNS
  • Disable DNS: Manually disable Private DNS

Troubleshooting

App Won't Connect/Disconnect

  1. Check Tailscale: Ensure Tailscale app is installed and authenticated
  2. Verify Permissions: Grant all requested permissions
  3. Check Logs: Use adb logcat | grep -i tailscale to see broadcast attempts
  4. Manual Test: Try manual connect/disconnect buttons first

Service Stops Unexpectedly

  1. Battery Optimization: Add app to battery optimization exceptions
    • Settings → Apps → [App Name] → Battery → Don't optimize
  2. Background Restrictions: Disable any OEM battery savers for this app
  3. Force Stop Test: Try manual service start/stop buttons

OEM-Specific Issues

Xiaomi/HyperOS:

# Disable battery optimization
Settings → Apps → [App Name] → Battery saver → No restrictions

Samsung:

# Disable adaptive battery
Settings → Apps → [App Name] → Battery → Optimize battery usage → Don't optimize

OnePlus/HydrogenOS:

# Recent apps → [App icon] → Lock (padlock icon)

Logs and Debugging

# View app logs
adb logcat | grep -i "tailscale\|NetworkMonitor"

# View all broadcasts
adb logcat | grep -i "broadcast"

# Check service status
adb shell dumpsys activity services | grep NetworkMonitor

Technical Details

Broadcast Intents

The app sends explicit broadcasts to Tailscale:

// Connect VPN
Intent("com.tailscale.ipn.CONNECT_VPN").apply {
    component = ComponentName("com.tailscale.ipn", "com.tailscale.ipn.IPNReceiver")
}

// Disconnect VPN
Intent("com.tailscale.ipn.DISCONNECT_VPN").apply {
    component = ComponentName("com.tailscale.ipn", "com.tailscale.ipn.IPNReceiver")
}

Architecture

  • UI Layer: Jetpack Compose + ViewModel
  • Data Layer: DataStore Preferences for settings
  • Service Layer: Foreground service with NetworkCallback
  • Broadcast Layer: Explicit intents to Tailscale

Permissions

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

Limitations & Known Issues

Tailscale Mode:

  1. App Switching: 2.5s visible interruption when launching Tailscale
  2. Tailscale Dependency: Requires Tailscale app to be installed
  3. Broadcast Compatibility: May break if Tailscale changes their broadcast API

Private DNS Mode:

  1. ADB Requirement: One-time setup requires computer with ADB
  2. DNS Only: No VPN tunneling, only DNS queries are affected
  3. Android 9+ Only: Older devices not supported

Both Modes:

  1. OEM Restrictions: Some manufacturers heavily restrict background services
  2. WiFi SSID Filtering: Current version connects/disconnects on any WiFi (SSID whitelist in future version)
  3. Location Permission: Not required in current version (needed for SSID detection in future)

Development

Project Structure

app/
├── src/main/
│   ├── AndroidManifest.xml
│   ├── java/com/antomate/tailscale/
│   │   ├── MainActivity.kt           # Compose UI
│   │   ├── MainViewModel.kt          # UI state management
│   │   ├── service/
│   │   │   ├── NetworkMonitorService.kt  # Foreground service
│   │   │   ├── NetworkMonitor.kt         # Network detection
│   │   │   └── TailscaleController.kt    # Broadcast sender
│   │   ├── data/
│   │   │   ├── SettingsRepository.kt     # DataStore wrapper
│   │   │   └── AppSettings.kt            # Data classes
│   │   └── receiver/
│   │       └── BootReceiver.kt           # Auto-start on boot
│   └── res/                              # Resources
└── build.gradle.kts                      # Dependencies

Testing

# Run unit tests
./gradlew testDebugUnitTest

# Run instrumentation tests (requires device/emulator)
./gradlew connectedDebugAndroidTest

License

This project is provided as-is for educational and personal use.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make changes with tests
  4. Submit a pull request

Why Private DNS Mode?

If you're frustrated with Tailscale's unreliable broadcast receiver and the annoying app-switching behavior, Private DNS mode is your solution!

Advantages over Tailscale Mode:

  • No app interruption - Changes happen instantly in the background
  • More reliable - Direct system API calls, no dependency on Tailscale app
  • Faster - No 2.5s delay waiting for Tailscale to launch
  • Less battery usage - No need to launch another app
  • Great for ad-blocking - Use DNS-based ad blockers like AdGuard DNS

When to use each mode:

Use Tailscale Mode if:

  • You need full VPN tunneling (not just DNS)
  • You want encrypted traffic routing through Tailscale network
  • You're okay with the brief app-switching interruption

Use Private DNS Mode if:

  • You mainly want DNS-based features (ad blocking, privacy DNS)
  • You want instant, seamless switching
  • You're tired of Tailscale's app-switching behavior
  • You have access to ADB for one-time setup

Future Enhancements

  • WiFi SSID whitelist/blacklist
  • Advanced diagnostics page
  • Log export functionality
  • Retry logic with exponential backoff
  • VpnService fallback for direct VPN control
  • Per-SSID automation rules
  • Different DNS servers for different WiFi networks

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Contributors

Languages