Skip to content

Set up dummy vpn for prevent internet connection for specific apps

License

Notifications You must be signed in to change notification settings

iamalper/flutter_blackhole_vpn

Repository files navigation

Blackhole Vpn sets up a vpn client for prevent connections for selected apps.

Android has VpnManager api and it is possible to create a vpn connection for specified apps. With this plugin, selected apps network will managed by a dummy vpn which don't make any connection.

Does not require root.

Supported platforms

  • Android

Any PR for other platforms is appreciated

Use cases

Firewall apps, data saving apps

How to use

This plugin uses BIND_VPN_SERVICE permission for setting up vpnservice.

If you want to publish your app to Google Play Store you need to document the use of vpnservice at store listing. See more at here

No need to edit AndroidManifest.xml

Make sure to minimum sdk version is 21 or above in android/app/build.gradle

defaultConfig {
    minSdkVersion 21
}

Import the package

All the methods below are available after importing the package and getting the instance of the plugin.

import 'package:blackhole_vpn/blackhole_vpn.dart';
final blackholeVpn = BlackholeVpnPlatform.instance;

Start Vpn for specified apps

You have to know package names for the apps do you want to use the blackhole vpn. Example app uses android_package_manager plugin.

 //Request permission then start blackhole vpn for specified apps
await blackholeVpn.runVpnService(["com.google.youtube","com.android.chrome"]);

Specified apps will not able to connect internet and local network. Returns bool whether the user accepted permission.

Check if blackhole vpn active

await blackholeVpn.isActive(); //Returns bool

Stop blackhole vpn

await blackholeVpn.stopVpn(); //Alternatively user can stop it via vpn notification or system settings

Tracking vpn state changes

Android let users to start or stop vpn service via vpn notification or system settings. You can track vpn state changes with specified methods.

  • Using VpnStateObserver widget

    VpnStateObserver(
        builder: (isActive) => switch (isActive) {
                true => Text("Blackhole vpn active"),
                false => Text(
                    "Blackhole vpn not active"),
                null => Text("Loading")
            })
  • Listening vpnStatusStream

    blackholeVpn.vpnStatusStream.listen((isActive) {
        if (isActive) {
            print("Blackhole vpn active");
        } else {
            print("Blackhole vpn not active");
        }
    });

    vpnStatusStream is a broadcast stream, it can be listened multiple times. It may not emit any value if vpn state is not changed. Checking state with isActive() before listen is recommended.

Testing

import 'package:flutter_test/flutter_test.dart';
import 'package:blackhole_vpn/blackhole_vpn.dart';
import 'package:blackhole_vpn/blackhole_vpn_platform_interface.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';

class TestBlackholeVpnPlatform
    with MockPlatformInterfaceMixin
    implements BlackholeVpnPlatform {
  var _isActive = false;
  @override
  Future<bool> runVpnService(_) async {
    _isActive = true;
    return true;
  }

  @override
  Future<bool> isActive() async {
    return _isActive;
  }

  @override
  Future<void> stopVpnService() async {
    _isActive = false;
  }

  @override
  Stream<bool> getVpnStatusStream() => throw UnimplementedError();
}

void main() {
  BlackholeVpnPlatform.instance = TestBlackholeVpnPlatform();
  test('test runVpnService', () async {
    final blackholeVpn = BlackholeVpnPlatform.instance;
    expect(await blackholeVpn.runVpnService([]), isTrue);
    expect(await blackholeVpn.isActive(), isTrue);
  });
}

About

Set up dummy vpn for prevent internet connection for specific apps

Topics

Resources

License

Stars

Watchers

Forks