Convert Figma logo to code with AI

Mygod logoVPNHotspot

Share your VPN connection over hotspot or repeater! (root required)

6,176
536
6,176
23

Top Related Projects

A shadowsocks client for Android

14,268

OpenVPN is an open source VPN daemon

Mirror only. Official repository is at https://git.zx2c4.com/wireguard-android

Official ProtonVPN Android app

23,459

Streisand sets up a new server running your choice of WireGuard, OpenConnect, OpenSSH, OpenVPN, Shadowsocks, sslh, Stunnel, or a Tor bridge. It also generates custom instructions for all of these services. At the end of the run you are given an HTML file with instructions that can be shared with friends, family members, and fellow activists.

Quick Overview

VPNHotspot is an Android app that allows users to share their VPN connection via Wi-Fi hotspot or USB tethering. It enables devices without native VPN support to benefit from a VPN connection, and it works with various VPN protocols.

Pros

  • Enables sharing of VPN connection to devices without built-in VPN support
  • Supports both Wi-Fi hotspot and USB tethering methods
  • Works with multiple VPN protocols (OpenVPN, WireGuard, etc.)
  • Open-source project with active development and community support

Cons

  • Requires root access on the Android device
  • May not work on all Android devices due to hardware and software variations
  • Potential battery drain when used extensively
  • Might conflict with some device-specific network settings or manufacturer modifications

Getting Started

To use VPNHotspot:

  1. Ensure your Android device is rooted.
  2. Download the app from the GitHub releases page or Google Play Store.
  3. Install the app and grant necessary permissions.
  4. Connect to your VPN service.
  5. Open VPNHotspot and configure your hotspot or tethering settings.
  6. Enable the hotspot or tethering feature to share your VPN connection.

Note: Specific steps may vary depending on your Android device and VPN service. Always refer to the official documentation for the most up-to-date instructions.

Competitor Comparisons

A shadowsocks client for Android

Pros of shadowsocks-android

  • More established project with a larger user base and community support
  • Offers a wider range of encryption methods and protocols
  • Includes features like route management and plugin system

Cons of shadowsocks-android

  • More complex setup and configuration process
  • Larger app size due to additional features
  • May consume more system resources

Code Comparison

VPNHotspot focuses on creating a Wi-Fi hotspot using Android's VPN API:

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    super.onStartCommand(intent, flags, startId)
    if (intent?.getBooleanExtra(EXTRA_ACTIVE, false) == true) startRunner() else stopRunner()
    return Service.START_STICKY
}

shadowsocks-android implements the Shadowsocks protocol for secure proxy connections:

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    if (BaseService.usingVpnMode) {
        if (prepare(this) != null) {
            startActivity(Intent(this, VpnRequestActivity::class.java)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
        } else {
            startVpn()
        }
    }
    return Service.START_STICKY
}

Both projects use Kotlin and implement Android services, but their core functionalities differ significantly.

14,268

OpenVPN is an open source VPN daemon

Pros of OpenVPN

  • Widely adopted and well-established VPN protocol
  • Extensive documentation and community support
  • Cross-platform compatibility (Windows, macOS, Linux, mobile)

Cons of OpenVPN

  • More complex setup and configuration process
  • Higher resource consumption compared to lightweight alternatives
  • Slower connection speeds due to encryption overhead

Code Comparison

OpenVPN (server configuration snippet):

port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem

VPNHotspot (Android app code snippet):

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    super.onStartCommand(intent, flags, startId)
    if (intent?.getBooleanExtra(KEY_RESTART, false) == true) {
        stop()
        start()
    }
    return Service.START_STICKY
}

While OpenVPN is a full-fledged VPN protocol implementation, VPNHotspot is an Android app designed to share VPN connections via Wi-Fi hotspot or USB tethering. OpenVPN offers more flexibility and security features, but VPNHotspot provides a simpler solution for sharing VPN connections on Android devices. The code snippets highlight the difference in complexity and focus between the two projects.

Mirror only. Official repository is at https://git.zx2c4.com/wireguard-android

Pros of wireguard-android

  • Implements the official WireGuard protocol, ensuring compatibility and security
  • Lightweight and efficient, optimized for mobile devices
  • Regularly updated and maintained by the WireGuard team

Cons of wireguard-android

  • Limited to WireGuard protocol only, less versatile than VPNHotspot
  • Lacks additional features like hotspot sharing or tethering

Code Comparison

VPNHotspot:

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    if (intent == null) return START_NOT_STICKY
    val data = intent.data
    if (data != null) when (data.scheme) {
        "quicktile" -> QuickToggleTileService.toggle(this)
        "widget" -> RepeaterWidget.toggle(this)
    }
    return super.onStartCommand(intent, flags, startId)
}

wireguard-android:

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    if (intent == null || intent.action == null) {
        return Service.START_NOT_STICKY
    }
    when (intent.action) {
        Intent.ACTION_BOOT_COMPLETED -> onBootCompleted()
        else -> return Service.START_NOT_STICKY
    }
    return Service.START_STICKY
}

Both projects use Kotlin and handle intent-based actions in their services, but VPNHotspot includes more specific functionality for quick toggles and widgets, while wireguard-android focuses on boot completion and core VPN service management.

Official ProtonVPN Android app

Pros of android-app

  • Comprehensive VPN solution with a wide range of server locations
  • Robust security features, including strong encryption and no-logs policy
  • Regular updates and active development from a reputable VPN provider

Cons of android-app

  • Larger codebase and more complex setup compared to VPNHotspot
  • Requires a subscription for full functionality
  • May consume more system resources due to its extensive feature set

Code Comparison

VPNHotspot (MainActivity.kt):

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    setSupportActionBar(findViewById(R.id.toolbar))
}

android-app (MainActivity.kt):

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    setupToolbar()
    setupNavigation()
    setupViewModel()
}

The android-app code shows a more complex setup with additional method calls, reflecting its broader feature set compared to VPNHotspot's simpler implementation.

23,459

Streisand sets up a new server running your choice of WireGuard, OpenConnect, OpenSSH, OpenVPN, Shadowsocks, sslh, Stunnel, or a Tor bridge. It also generates custom instructions for all of these services. At the end of the run you are given an HTML file with instructions that can be shared with friends, family members, and fellow activists.

Pros of Streisand

  • Supports multiple VPN protocols (OpenVPN, WireGuard, etc.)
  • Automates server setup and configuration
  • Provides a comprehensive suite of privacy-enhancing tools

Cons of Streisand

  • More complex setup process
  • Requires a dedicated server or cloud instance
  • Less suitable for mobile devices or local network sharing

Code Comparison

Streisand (server setup):

./streisand

VPNHotspot (Android app initialization):

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
}

Summary

Streisand is a comprehensive solution for setting up VPN servers with various protocols and privacy tools, ideal for users seeking a full-featured privacy infrastructure. VPNHotspot, on the other hand, is an Android app focused on creating local VPN hotspots, making it more suitable for mobile users who want to share their VPN connection with other devices on the go. While Streisand offers more versatility in terms of VPN protocols and server-side features, VPNHotspot provides a simpler, more accessible solution for mobile users looking to extend their VPN protection to other devices on their local network.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

VPN Hotspot

Releases Android 10-17

Get it on Obtainium (Pre-release channel)

Connecting things to your VPN made simple. Share your VPN connection over hotspot or repeater. (root required)

This app is useful for:

  • Connecting things that don't support VPN like Chromecasts behind corporate firewalls;
  • Setting up gapps behind corporate firewalls;
  • Connecting to your mobile hotspot but you're not bothered to set up VPN on your device;
  • Identifying, monitoring and blocking (unwanted) clients;
  • Bypassing tethering limits by:
    • (recommended) Use this app with a real VPN/socksifier;
    • Use this app with some adblock/DNS apps that uses system VPN service APIs, i.e. fake VPNs; (troubleshooting/a list of apps that work)
    • Try your luck and simply use this app.

P.S. You can also do the similar on Windows, Mac, and iOS.

Features That Requires System App Installation

The following features in the app requires it to be installed under /system/priv-app since some restricted permissions are required. One way to do this is to use App systemizer for Magisk.

  • (Android 8-10, since app v2.4.0) android.permission.OVERRIDE_WIFI_CONFIG: Read/write system Wi-Fi hotspot configuration. (#117)

Installing as system app also has the side benefit of launching root daemon less frequently due to having privileged permissions listed below.

  • android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS
  • android.permission.LOCAL_MAC_ADDRESS
  • android.permission.MANAGE_USB
  • android.permission.OVERRIDE_WIFI_CONFIG
  • android.permission.READ_WIFI_CREDENTIAL
  • android.permission.TETHER_PRIVILEGED
  • android.permission.WRITE_SECURE_SETTINGS
  • Other system-app exclusive features that are not gated by permissions.

Whenever you install an app update, if there was a new protected permission addition (last updated in v2.17.1), you should update the app installed in system as well to make the system grant the privileged permission.

Q & A

Search the issue tracker for more.

What persistent changes can this app do to my system?

This app only indirectly write persistent changes through system APIs thus it should be generally pretty safe.

  1. In Supplicant mode, the repeater asks wpa_supplicant to create a persistent group on startup, which Android persists in /data/vendor/wifi/wpa/p2p_supplicant.conf or /data/misc/wifi/p2p_supplicant.conf.
  2. If you edited the system Wi-Fi hotspot configuration through this app, those changes will persist.
  3. If you toggle tethering hardware offload through this app, the Android global tether_offload_disabled setting will persist. Toggle it back in this app or the matching Developer options setting to revert it.

Routing, firewall, addresses, and daemon/service state managed by this app are cleaned up when stopped, by Clean, or upon reboot.

No root?

Failed to create group due to internal error/repeater shuts down after a while?

This could caused by the Wi-Fi channel you selected is no longer available, due to:

  1. Your device doesn't support operating on this channel, or
  2. There is some nearby Wi-Fi direct device that broadcasted that it can't operate on the channel you picked.

For maximum stability, you need to set channel = 0 so that your device will pick a channel automatically. You can also use WPS to connect your 2.4GHz-only device to force the repeater to switch from 5GHz to 2.4GHz for this time.

Private APIs used / Assumptions for Android customizations

a.k.a. things that can go wrong if this app doesn't work.

This is a list of stuff that might impact this app's functionality if unavailable. This is only meant to be an index. You can read more in the source code. API restrictions are updated up to SHA-256 checksum 9102af02fe6ab68b92464bdff5e5b09f3bd62c65d1130aaf85d3296f17d38074.

Greylisted/blacklisted APIs or internal constants: (some constants are hardcoded or implicitly used)

  • (prior to API 30) Landroid/net/ConnectivityManager;->getLastTetherError(Ljava/lang/String;)I,max-target-r
  • (prior to API 30) Landroid/net/ConnectivityManager;->EXTRA_ACTIVE_LOCAL_ONLY:Ljava/lang/String;,lo-prio,max-target-o
  • (prior to API 30) Landroid/net/ConnectivityManager;->EXTRA_ACTIVE_TETHER:Ljava/lang/String;,max-target-r
  • (prior to API 30) Landroid/net/ConnectivityManager;->EXTRA_AVAILABLE_TETHER:Ljava/lang/String;,max-target-r
  • (prior to API 30) Landroid/net/ConnectivityManager;->ACTION_TETHER_STATE_CHANGED:Ljava/lang/String;,max-target-r
  • (prior to API 30) Landroid/net/ConnectivityManager;->EXTRA_ERRORED_TETHER:Ljava/lang/String;,max-target-r
  • (since API 30) Landroid/net/ConnectivityModuleConnector;->IN_PROCESS_SUFFIX:Ljava/lang/String;
  • (since API 31) Landroid/net/INetd$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetd;
  • (since API 31) Landroid/net/INetd;->ipSecUpdateSecurityPolicy(IIILjava/lang/String;Ljava/lang/String;IIII)V
  • (since API 30) Landroid/net/IIntResultListener$Stub;-><init>()V,blocked
  • (since API 30) Landroid/net/IIntResultListener;->onResult(I)V,blocked
  • (since API 30) Landroid/net/ITetheringConnector;->stopTethering(ILjava/lang/String;Landroid/net/IIntResultListener;)V,blocked
  • (since API 30) Landroid/net/ITetheringConnector;->stopTethering(ILjava/lang/String;Ljava/lang/String;Landroid/net/IIntResultListener;)V,blocked
  • (since API 30) Landroid/net/TetheringManager$ConnectorConsumer;->onConnectorAvailable(Landroid/net/ITetheringConnector;)V,blocked
  • (since API 30) Landroid/net/TetheringManager$TetheringEventCallback;->onTetherableInterfaceRegexpsChanged(Landroid/net/TetheringManager$TetheringInterfaceRegexps;)V,blocked
  • (since API 31) Landroid/net/TetheringManager$TetheringEventCallback;->onSupportedTetheringTypes(Ljava/util/Set;)V,blocked
  • (since API 30) Landroid/net/TetheringManager;->getConnector(Landroid/net/TetheringManager$ConnectorConsumer;)V,blocked
  • Landroid/net/TetheringManager;->TETHER_ERROR_*:I,blocked
  • (since API 30) Landroid/net/TetheringManager;->TETHERING_VIRTUAL:I,blocked
  • (since API 30) Landroid/net/TetheringManager;->TETHERING_WIGIG:I,blocked
  • (since API 31) Landroid/net/IpSecManager;->DIRECTION_FWD:I,blocked
  • (since API 31) Landroid/net/IpSecManager;->INVALID_SECURITY_PARAMETER_INDEX:I,blocked
  • (since API 31) Landroid/net/wifi/SoftApCapability;->getCountryCode()Ljava/lang/String;,blocked
  • (since API 33) Landroid/net/wifi/SoftApConfiguration$Builder;->setRandomizedMacAddress(Landroid/net/MacAddress;)Landroid/net/wifi/SoftApConfiguration$Builder;,blocked
  • (since API 31) Landroid/net/wifi/SoftApConfiguration;->BAND_TYPES:[I,blocked
  • (since API 31) Landroid/net/wifi/SoftApInfo;->getApInstanceIdentifier()Ljava/lang/String;,blocked
  • Landroid/net/wifi/ISoftApCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/ISoftApCallback;,lo-prio,max-target-o
  • (since API 33) Landroid/net/wifi/IWifiManager;->registerLocalOnlyHotspotSoftApCallback(Landroid/net/wifi/ISoftApCallback;Landroid/os/Bundle;)V,blocked
  • (prior to API 31) Landroid/net/wifi/IWifiManager;->registerSoftApCallback(Landroid/os/IBinder;Landroid/net/wifi/ISoftApCallback;I)V,max-target-o
  • (since API 31) Landroid/net/wifi/IWifiManager;->registerSoftApCallback(Landroid/net/wifi/ISoftApCallback;)V,blocked
  • (since API 33) Landroid/net/wifi/IWifiManager;->unregisterLocalOnlyHotspotSoftApCallback(Landroid/net/wifi/ISoftApCallback;Landroid/os/Bundle;)V,blocked
  • (prior to API 31) Landroid/net/wifi/IWifiManager;->unregisterSoftApCallback(I)V,max-target-o
  • (since API 31) Landroid/net/wifi/IWifiManager;->unregisterSoftApCallback(Landroid/net/wifi/ISoftApCallback;)V,blocked
  • (since API 31) Landroid/net/wifi/WifiClient;->getApInstanceIdentifier()Ljava/lang/String;,blocked
  • (prior to API 30) Landroid/net/wifi/WifiConfiguration;->AP_BAND_2GHZ:I,lo-prio,max-target-o
  • (prior to API 30) Landroid/net/wifi/WifiConfiguration;->AP_BAND_5GHZ:I,lo-prio,max-target-o
  • (prior to API 30) Landroid/net/wifi/WifiConfiguration;->AP_BAND_ANY:I,lo-prio,max-target-o
  • (prior to API 30) Landroid/net/wifi/WifiConfiguration;->apBand:I,unsupported
  • (prior to API 30) Landroid/net/wifi/WifiConfiguration;->apChannel:I,unsupported
  • (since API 30) Landroid/net/wifi/WifiContext;->ACTION_RESOURCES_APK:Ljava/lang/String;,blocked
  • (since API 30) Landroid/net/wifi/WifiContext;-><init>(Landroid/content/Context;)V,blocked
  • (prior to API 30) Landroid/net/wifi/WifiManager$SoftApCallbackProxy;-><init>(Landroid/os/Looper;Landroid/net/wifi/WifiManager$SoftApCallback;)V,max-target-o
  • (since API 30, prior to API 33) Landroid/net/wifi/WifiManager$SoftApCallbackProxy;-><init>(Landroid/net/wifi/WifiManager;Ljava/util/concurrent/Executor;Landroid/net/wifi/WifiManager$SoftApCallback;)V,blocked
  • (since API 33) Landroid/net/wifi/WifiManager$SoftApCallbackProxy;-><init>(Landroid/net/wifi/WifiManager;Ljava/util/concurrent/Executor;Landroid/net/wifi/WifiManager$SoftApCallback;I)V,blocked
  • (prior to API 30) Landroid/net/wifi/WifiManager$SoftApCallback;->onNumClientsChanged(I)V,greylist-max-o
  • (since API 33) Landroid/net/wifi/WifiManager;->EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE:Ljava/lang/String;,blocked
  • Landroid/net/wifi/WifiManager;->cancelLocalOnlyHotspotRequest()V,unsupported
  • Landroid/net/wifi/WifiManager;->mService:Landroid/net/wifi/IWifiManager;,unsupported
  • Landroid/net/wifi/p2p/WifiP2pConfig$Builder;->MAC_ANY_ADDRESS:Landroid/net/MacAddress;,blocked
  • Landroid/net/wifi/p2p/WifiP2pConfig$Builder;->mNetworkName:Ljava/lang/String;,blocked
  • (since API 30) Landroid/net/wifi/p2p/WifiP2pGroup;->interfaceAddress:[B,unsupported
  • Landroid/net/wifi/p2p/WifiP2pManager;->startWps(Landroid/net/wifi/p2p/WifiP2pManager$Channel;Landroid/net/wifi/WpsInfo;Landroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V,unsupported
  • Landroid/hardware/wifi/supplicant/V1_0/IfaceType;->P2P:I
  • Landroid/hardware/wifi/supplicant/V1_0/ISupplicant;->getService()Landroid/hardware/wifi/supplicant/V1_0/ISupplicant;
  • Landroid/hardware/wifi/supplicant/V1_0/ISupplicant;->getInterface(Landroid/hardware/wifi/supplicant/V1_0/ISupplicant$IfaceInfo;Landroid/hardware/wifi/supplicant/V1_0/ISupplicant$getInterfaceCallback;)V
  • Landroid/hardware/wifi/supplicant/V1_0/ISupplicant$getInterfaceCallback;->onValues(Landroid/hardware/wifi/supplicant/V1_0/SupplicantStatus;Landroid/hardware/wifi/supplicant/V1_0/ISupplicantIface;)V
  • Landroid/hardware/wifi/supplicant/V1_0/ISupplicant;->listInterfaces(Landroid/hardware/wifi/supplicant/V1_0/ISupplicant$listInterfacesCallback;)V
  • Landroid/hardware/wifi/supplicant/V1_0/ISupplicant$IfaceInfo;->name:Ljava/lang/String;
  • Landroid/hardware/wifi/supplicant/V1_0/ISupplicant$IfaceInfo;->type:I
  • Landroid/hardware/wifi/supplicant/V1_0/ISupplicant$listInterfacesCallback;->onValues(Landroid/hardware/wifi/supplicant/V1_0/SupplicantStatus;Ljava/util/ArrayList;)V
  • Landroid/hardware/wifi/supplicant/V1_0/ISupplicantP2pIface;->asInterface(Landroid/os/IHwBinder;)Landroid/hardware/wifi/supplicant/V1_0/ISupplicantP2pIface;
  • Landroid/hardware/wifi/supplicant/V1_0/SupplicantStatus;->code:I
  • Landroid/hardware/wifi/supplicant/V1_0/SupplicantStatus;->debugMessage:Ljava/lang/String;
  • Landroid/hardware/wifi/supplicant/V1_2/ISupplicantP2pIface;->addGroup_1_2(Ljava/util/ArrayList;Ljava/lang/String;ZI[BZ)Landroid/hardware/wifi/supplicant/V1_0/SupplicantStatus;
  • Landroid/hardware/wifi/supplicant/V1_2/ISupplicantP2pIface;->castFrom(Landroid/os/IHwInterface;)Landroid/hardware/wifi/supplicant/V1_2/ISupplicantP2pIface;
  • Landroid/hardware/wifi/supplicant/V1_2/ISupplicantP2pIface;->setMacRandomization(Z)Landroid/hardware/wifi/supplicant/V1_0/SupplicantStatus;
  • (since API 30) Landroid/os/ServiceManager;->waitForDeclaredService(Ljava/lang/String;)Landroid/os/IBinder;,blocked
  • (since API 30) Landroid/os/ServiceManager;->waitForService(Ljava/lang/String;)Landroid/os/IBinder;,blocked
  • (since API 30) Lcom/android/server/wifi/SupplicantStaIfaceHalAidlMainlineImpl;->isServiceAvailable(Landroid/content/Context;)Z
  • (since API 30) Landroid/system/wifi/mainline_supplicant/IMainlineSupplicant$Stub;->asInterface(Landroid/os/IBinder;)Landroid/system/wifi/mainline_supplicant/IMainlineSupplicant;
  • (since API 30) Landroid/system/wifi/mainline_supplicant/IMainlineSupplicant;->getVendorSupplicant()Lcom/android/wifi/x/android/hardware/wifi/supplicant/ISupplicant;
  • (prior to API 30) Landroid/provider/Settings$Global;->SOFT_AP_TIMEOUT_ENABLED:Ljava/lang/String;,lo-prio,max-target-o
  • (on API 34) Landroid/service/quicksettings/TileService;->mToken:Landroid/os/IBinder;,lo-prio,max-target-o
  • (prior to API 30) Lcom/android/internal/R$array;->config_tether_bluetooth_regexs:I,max-target-q
  • (prior to API 30) Lcom/android/internal/R$array;->config_tether_usb_regexs:I,max-target-q
  • (prior to API 30) Lcom/android/internal/R$array;->config_tether_wifi_regexs:I,max-target-q
  • (on API 29) Lcom/android/internal/R$bool;->config_wifi_p2p_mac_randomization_supported:I,blacklist
  • (prior to API 30) Lcom/android/internal/R$integer;->config_wifi_framework_soft_ap_timeout_delay:I,greylist-max-o
  • Lcom/android/internal/R$string;->config_ethernet_iface_regex:I,lo-prio,max-target-o
  • (since API 31) Lcom/android/server/IpSecService;->FULL_MASK:I
  • (since API 30) Lcom/android/server/wifi/p2p/SupplicantP2pIfaceHalAidlBase;->HAL_INSTANCE_NAME:Ljava/lang/String;
  • (since API 30) Lcom/android/server/wifi/p2p/SupplicantP2pIfaceHalAidlMainlineImpl;->MAINLINE_SUPPLICANT_SERVICE_NAME:Ljava/lang/String;
  • Lcom/android/server/wifi/p2p/WifiP2pServiceImpl;->ANONYMIZED_DEVICE_ADDRESS:Ljava/lang/String;
  • (since API 30) Lcom/android/server/SystemServer;->TETHERING_CONNECTOR_CLASS:Ljava/lang/String;
  • (since API 33) Ldalvik/system/BaseDexClassLoader;->pathList:Ldalvik/system/DexPathList;,unsupported
  • (since API 33) Ldalvik/system/DexPathList;->nativeLibraryDirectories:Ljava/util/List;,unsupported
  • (prior to API 33) Ljava/lang/invoke/MethodHandles$Lookup;-><init>(Ljava/lang/Class;I)V,unsupported
  • (prior to API 33) Ljava/lang/invoke/MethodHandles$Lookup;->ALL_MODES:I,lo-prio,max-target-o

See mobile/src/hiddenApiStubs for hidden whitelisted/system APIs as well as partial SDK-class stubs.

Nonexported system resources:

  • (since API 30) @com.android.networkstack.tethering:array/config_tether_bluetooth_regexs
  • (since API 30) @com.android.networkstack.tethering:array/config_tether_ncm_regexs
  • (since API 30) @com.android.networkstack.tethering:array/config_tether_usb_regexs
  • (since API 30) @com.android.networkstack.tethering:array/config_tether_wifi_p2p_regexs
  • (since API 30) @com.android.networkstack.tethering:array/config_tether_wifi_regexs
  • (since API 30) @com.android.networkstack.tethering:array/config_tether_wigig_regexs
  • (since API 30) @com.android.wifi.resources:bool/config_wifi_p2p_mac_randomization_supported
  • (since API 31) @com.android.wifi.resources:integer/config_wifiFrameworkSoftApShutDownIdleInstanceInBridgedModeTimeoutMillisecond
  • (since API 30) @com.android.wifi.resources:integer/config_wifiFrameworkSoftApShutDownTimeoutMilliseconds

Other:

  • (prior to API 30) Activity com.android.settings/.Settings$TetherSettingsActivity is assumed to be exported.
  • P2P HIDL fallback probes generated supplicant HIDL Java classes from Android 10 wifi-service.jar and Android 11+ AOSP Wi-Fi service-wifi.jar com.android.wifi.x.* jarjar packages.
  • P2P AIDL mode probes the Wi-Fi mainline service wifi_mainline_supplicant from live service-wifi.jar to recover the stable vendor supplicant AIDL binder before falling back to direct vendor HAL registration.
  • IPv6 NAT mode depends on the iptables TPROXY and NFQUEUE targets and transparent sockets. ICMPv6 Echo interception uses app-owned queue 30000 and assumes queued downstream packets expose six-byte source hardware-address metadata through NFQA_HWADDR.
  • (since API 30) Relevant tethering APEX classes used here, including android.net.ITetheringConnector, may be jarjar-relocated under the optional prefixes android.net.connectivity or com.android.connectivity.
  • (since API 31) Relevant netd APEX classes used here, including android.net.INetd*, may be jarjar-relocated under the optional prefixes android.net.connectivity or com.android.connectivity.
  • (since API 30) When runtime TetheringEventCallback.onLocalOnlyInterfacesChanged is present, AOSP dispatches startup tether-state callbacks from one executor.execute { ... } block in onCallbackStarted, and later tether-state updates from one executor.execute { ... } block in onTetherStatesChanged.
  • The Rust DNS proxy submits upstream queries through android_res_nsend/android_res_nresult. To keep daemon tasks nonblocking while still using android_res_nresult as the public result reader/closer, it waits for dnsproxyd to close the one-shot resnsend client socket before reading the result. This assumes resnsend writes the complete resolver result before returning and the socket receive buffer can hold that result until the framework socket listener closes the client socket.
  • For ip rule priorities, AOSP local-network/tethering priorities are assumed to be 17000/18000 on API 29..30 and 20000/21000 on API 31+. VPNHotspot uses the 17500..17900 or 20500..20900 gap between them.
  • For route-table numbers, Android interface tables are assumed to start at ifindex + 1000; IPv6 NAT TPROXY uses table 900 to stay below that range and away from AOSP fixed tables 97..99 and kernel built-ins.
  • Clean flushes table 900 because that table is reserved by VPNHotspot. IPv6 NAT also adds its deterministic ULA /64 route to Android's shared local_network route table 97; Clean never flushes that table and only deletes VPNHotspot prefixes reconstructed from current interface names.
  • For packet marks, Android fwmark is assumed to use low bits for netId and routing metadata.
  • IPv6 NAT fwmark fallback for TPROXY uses masked high reserved bits 0x10000000/0x10000000. That fallback is expected on only kernels without effective FRA_IP_PROTO policy-rule support, which upstream Linux added in 4.17.
  • Daemon reply sockets use the AOSP local-network protected mark 0x00030063, which assumes LOCAL_NET_ID = 99 plus the explicitlySelected and protectedFromVpn fwmark bits.

System/root command assumptions:

The following Android system binaries are assumed to be bundled and executable:

  • /system/bin/dumpsys (ipsec);
  • /system/bin/iptables-restore, /system/bin/ip6tables-restore (-w --noflush, restore input commands including -I, -D, -N, -nvx -L <chain>);
  • /system/bin/ndc (ipfwd, nat);
  • /system/bin/settings (put global);
  • /system/bin/linker or /system/bin/linker64 (path.zip!/program).