Skip to content

Commit

Permalink
app blacklist
Browse files Browse the repository at this point in the history
  • Loading branch information
wanghongenpin committed Mar 31, 2024
1 parent 652b66b commit 7452a8f
Show file tree
Hide file tree
Showing 15 changed files with 210 additions and 30 deletions.
30 changes: 25 additions & 5 deletions android/app/src/main/kotlin/com/network/proxy/ProxyVpnService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class ProxyVpnService : VpnService(), ProtectSocket {
const val PROXY_HOST_KEY = "ProxyHost"
const val PROXY_PORT_KEY = "ProxyPort"
const val ALLOW_APPS_KEY = "AllowApps" //允许的名单
const val DISALLOW_APPS_KEY = "DisallowApps" //禁止的名单

/**
* 动作:断开连接
Expand All @@ -48,6 +49,7 @@ class ProxyVpnService : VpnService(), ProtectSocket {
var host: String? = null
var port: Int = 0
var allowApps: ArrayList<String>? = null
private var disallowApps: ArrayList<String>? = null

fun stopVpnIntent(context: Context): Intent {
return Intent(context, ProxyVpnService::class.java).also {
Expand All @@ -59,12 +61,14 @@ class ProxyVpnService : VpnService(), ProtectSocket {
context: Context,
proxyHost: String? = host,
proxyPort: Int? = port,
allowApps: ArrayList<String>? = this.allowApps
allowApps: ArrayList<String>? = this.allowApps,
disallowApps: ArrayList<String>? = this.disallowApps
): Intent {
return Intent(context, ProxyVpnService::class.java).also {
it.putExtra(PROXY_HOST_KEY, proxyHost)
it.putExtra(PROXY_PORT_KEY, proxyPort)
it.putStringArrayListExtra(ALLOW_APPS_KEY, allowApps)
it.putStringArrayListExtra(DISALLOW_APPS_KEY, disallowApps)
}
}
}
Expand All @@ -82,7 +86,8 @@ class ProxyVpnService : VpnService(), ProtectSocket {
connect(
intent.getStringExtra(PROXY_HOST_KEY) ?: host!!,
intent.getIntExtra(PROXY_PORT_KEY, port),
intent.getStringArrayListExtra(ALLOW_APPS_KEY) ?: allowApps
intent.getStringArrayListExtra(ALLOW_APPS_KEY) ?: allowApps,
intent.getStringArrayListExtra(DISALLOW_APPS_KEY)
)
START_STICKY
}
Expand All @@ -98,13 +103,19 @@ class ProxyVpnService : VpnService(), ProtectSocket {
isRunning = false
}

private fun connect(proxyHost: String, proxyPort: Int, allowPackages: ArrayList<String>?) {
private fun connect(
proxyHost: String,
proxyPort: Int,
allowPackages: ArrayList<String>?,
disallowPackages: ArrayList<String>?
) {
Log.i("ProxyVpnService", "startVpn $host:$port $allowApps")

host = proxyHost
port = proxyPort
allowApps = allowPackages
vpnInterface = createVpnInterface(proxyHost, proxyPort, allowPackages)
disallowApps = disallowPackages
vpnInterface = createVpnInterface(proxyHost, proxyPort, allowPackages, disallowPackages)
if (vpnInterface == null) {
val alertDialog = Intent(applicationContext, VpnAlertDialog::class.java)
.setAction("com.network.proxy.ProxyVpnService")
Expand Down Expand Up @@ -152,7 +163,12 @@ class ProxyVpnService : VpnService(), ProtectSocket {
}


private fun createVpnInterface(proxyHost: String, proxyPort: Int, allowPackages: List<String>?):
private fun createVpnInterface(
proxyHost: String,
proxyPort: Int,
allowPackages: List<String>?,
disallowApps: ArrayList<String>?
):
ParcelFileDescriptor? {
val build = Builder()
.setMtu(MAX_PACKET_LEN)
Expand All @@ -170,6 +186,10 @@ class ProxyVpnService : VpnService(), ProtectSocket {
build.addDisallowedApplication(baseContext.packageName)
}

disallowApps?.forEach {
build.addDisallowedApplication(it)
}

build.setConfigureIntent(
PendingIntent.getActivity(
this,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class PictureInPicturePlugin : AndroidFlutterPlugin() {
var channel: MethodChannel? = null
var proxyHost: String? = null
var proxyPort: Int? = null
var allowApps: ArrayList<String>? = null
var disallowApps: ArrayList<String>? = null

///广播事件接受者
private val vpnBroadcastReceiver = object : BroadcastReceiver() {
Expand All @@ -43,7 +45,15 @@ class PictureInPicturePlugin : AndroidFlutterPlugin() {
if (isRunning) {
activity.startService(ProxyVpnService.stopVpnIntent(activity))
} else {
activity.startService(ProxyVpnService.startVpnIntent(activity, proxyHost, proxyPort))
activity.startService(
ProxyVpnService.startVpnIntent(
activity,
proxyHost,
proxyPort,
allowApps,
disallowApps
)
)
}

//设置画中画参数
Expand All @@ -67,6 +77,8 @@ class PictureInPicturePlugin : AndroidFlutterPlugin() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
proxyHost = call.argument<String>("proxyHost")
proxyPort = call.argument<Int>("proxyPort")
allowApps = call.argument<ArrayList<String>>("allowApps")
disallowApps = call.argument<ArrayList<String>>("disallowApps")

val param = updatePictureInPictureParams(ProxyVpnService.isRunning)
if (!registerBroadcast) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ class VpnServicePlugin : AndroidFlutterPlugin() {
val host = call.argument<String>("proxyHost")
val port = call.argument<Int>("proxyPort")
val allowApps = call.argument<ArrayList<String>>("allowApps")
val disallowApps = call.argument<ArrayList<String>>("disallowApps")
val prepareVpn = prepareVpn(host!!, port!!, allowApps)
if (prepareVpn) {
startVpn(host, port, allowApps)
startVpn(host, port, allowApps, disallowApps)
}
result.success(prepareVpn)
}
Expand All @@ -39,8 +40,9 @@ class VpnServicePlugin : AndroidFlutterPlugin() {
val host = call.argument<String>("proxyHost")
val port = call.argument<Int>("proxyPort")
val allowApps = call.argument<ArrayList<String>>("allowApps")
val disallowApps = call.argument<ArrayList<String>>("disallowApps")
stopVpn()
startVpn(host!!, port!!, allowApps)
startVpn(host!!, port!!, allowApps, disallowApps)
}

else -> {
Expand Down Expand Up @@ -69,8 +71,13 @@ class VpnServicePlugin : AndroidFlutterPlugin() {
/**
* 启动vpn服务
*/
private fun startVpn(host: String, port: Int, allowApps: ArrayList<String>?) {
val intent = ProxyVpnService.startVpnIntent(activity, host, port, allowApps)
private fun startVpn(
host: String,
port: Int,
allowApps: ArrayList<String>?,
disallowApps: ArrayList<String>?
) {
val intent = ProxyVpnService.startVpnIntent(activity, host, port, allowApps, disallowApps)
activity.startService(intent)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class ProcessInfoManager private constructor() {
}

private val localPortUidMap =
CacheBuilder.newBuilder().maximumSize(10_000).expireAfterAccess(120, TimeUnit.SECONDS)
CacheBuilder.newBuilder().maximumSize(10_000).expireAfterAccess(60, TimeUnit.SECONDS)
.build<Int, Int>()

private val appInfoCache =
Expand Down
1 change: 1 addition & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
"domainBlacklist": "Domain Blacklist",
"domainFilter": "Domain Filter",
"appWhitelist": "App Whitelist",
"appBlacklist": "App Blacklist",
"scanCode": "Scan Code Connect",
"addBlacklist": "Add Filter Blacklist",
"addWhitelist": "Add Filter Whitelist",
Expand Down
1 change: 1 addition & 0 deletions lib/l10n/app_zh.arb
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
"domainWhitelist": "域名白名单",
"domainBlacklist" :"域名黑名单",
"appWhitelist": "应用白名单",
"appBlacklist": "应用黑名单",
"domainFilter": "域名过滤",
"scanCode": "扫码连接",
"addBlacklist": "添加黑名单",
Expand Down
7 changes: 4 additions & 3 deletions lib/native/pip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ class PictureInPicture {
});

///进入画中画模式
static Future<bool> enterPictureInPictureMode(String host, int port) async {
final bool enterPictureInPictureMode =
await _channel.invokeMethod('enterPictureInPictureMode', {"proxyHost": host, "proxyPort": port});
static Future<bool> enterPictureInPictureMode(String host, int port,
{List<String>? appList, List<String>? disallowApps}) async {
final bool enterPictureInPictureMode = await _channel.invokeMethod('enterPictureInPictureMode',
{"proxyHost": host, "proxyPort": port, "allowApps": appList, "disallowApps": disallowApps});
inPip = true;

return enterPictureInPictureMode;
Expand Down
12 changes: 6 additions & 6 deletions lib/native/vpn.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ class Vpn {

static bool isVpnStarted = false; //vpn是否已经启动

static startVpn(String host, int port, {List<String>? appList, bool? backgroundAudioEnable = true}) {
proxyVpnChannel.invokeMethod("startVpn",
{"proxyHost": host, "proxyPort": port, "allowApps": appList, "backgroundAudioEnable": backgroundAudioEnable});
static startVpn(String host, int port, {List<String>? appList, List<String>? disallowApps}) {
proxyVpnChannel.invokeMethod(
"startVpn", {"proxyHost": host, "proxyPort": port, "allowApps": appList, "disallowApps": disallowApps});
isVpnStarted = true;
}

Expand All @@ -17,9 +17,9 @@ class Vpn {
}

//重启vpn
static restartVpn(String host, int port, {List<String>? appList, bool? backgroundAudioEnable = true}) {
proxyVpnChannel.invokeMethod("restartVpn",
{"proxyHost": host, "proxyPort": port, "allowApps": appList, "backgroundAudioEnable": backgroundAudioEnable});
static restartVpn(String host, int port, {List<String>? appList, List<String>? disallowApps}) {
proxyVpnChannel.invokeMethod(
"restartVpn", {"proxyHost": host, "proxyPort": port, "allowApps": appList, "disallowApps": disallowApps});

isVpnStarted = true;
}
Expand Down
5 changes: 5 additions & 0 deletions lib/network/bin/configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class Configuration {
//白名单应用
List<String> appWhitelist = [];

//应用黑名单
List<String>? appBlacklist;

//远程连接 不持久化保存
String? remoteHost;

Expand Down Expand Up @@ -84,6 +87,7 @@ class Configuration {
externalProxy = ProxyInfo.fromJson(config['externalProxy']);
}
appWhitelist = List<String>.from(config['appWhitelist'] ?? []);
appBlacklist = config['appBlacklist'] == null ? null : List<String>.from(config['appBlacklist']);
HostFilter.whitelist.load(config['whitelist']);
HostFilter.blacklist.load(config['blacklist']);
}
Expand Down Expand Up @@ -131,6 +135,7 @@ class Configuration {
'proxyPassDomains': proxyPassDomains,
'externalProxy': externalProxy?.toJson(),
'appWhitelist': appWhitelist,
'appBlacklist': appBlacklist,
'historyCacheTime': historyCacheTime,
'whitelist': HostFilter.whitelist.toJson(),
'blacklist': HostFilter.blacklist.toJson(),
Expand Down
9 changes: 9 additions & 0 deletions lib/network/util/cache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ class ExpiringCache<K, V> {
_expirationTimes[key] = Timer(duration, () => remove(key));
}

V? putIfAbsent(K key, V Function() ifAbsent) {
if (_cache.containsKey(key)) {
return _cache[key];
}
final value = ifAbsent();
set(key, value);
return value;
}

V? get(K key) {
return _cache[key];
}
Expand Down
8 changes: 7 additions & 1 deletion lib/ui/mobile/menu/drawer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import 'package:network_proxy/ui/configuration.dart';
import 'package:network_proxy/ui/mobile/menu/preference.dart';
import 'package:network_proxy/ui/mobile/request/favorite.dart';
import 'package:network_proxy/ui/mobile/request/history.dart';
import 'package:network_proxy/ui/mobile/setting/app_whitelist.dart';
import 'package:network_proxy/ui/mobile/setting/app_filter.dart';
import 'package:network_proxy/ui/mobile/setting/filter.dart';
import 'package:network_proxy/ui/mobile/setting/request_block.dart';
import 'package:network_proxy/ui/mobile/setting/request_rewrite.dart';
Expand Down Expand Up @@ -153,6 +153,12 @@ class FilterMenu extends StatelessWidget {
title: Text(localizations.appWhitelist),
trailing: const Icon(Icons.arrow_right),
onTap: () => navigator(context, AppWhitelist(proxyServer: proxyServer))),
Platform.isIOS
? const SizedBox()
: ListTile(
title: Text(localizations.appBlacklist),
trailing: const Icon(Icons.arrow_right),
onTap: () => navigator(context, AppBlacklist(proxyServer: proxyServer))),
])));
}
}
7 changes: 4 additions & 3 deletions lib/ui/mobile/mobile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ class MobileHomeState extends State<MobileHomePage> implements EventListener, Li
}

return PictureInPicture.enterPictureInPictureMode(
Platform.isAndroid ? await localIp() : "127.0.0.1", proxyServer.port);
Platform.isAndroid ? await localIp() : "127.0.0.1", proxyServer.port,
appList: proxyServer.configuration.appWhitelist, disallowApps: proxyServer.configuration.appBlacklist);
}
return false;
}
Expand Down Expand Up @@ -207,8 +208,8 @@ class MobileHomeState extends State<MobileHomePage> implements EventListener, Li
serverLaunch: false,
onStart: () async {
Vpn.startVpn(Platform.isAndroid ? await localIp() : "127.0.0.1", proxyServer.port,
backgroundAudioEnable: widget.appConfiguration.iosVpnBackgroundAudioEnable,
appList: proxyServer.configuration.appWhitelist);
appList: proxyServer.configuration.appWhitelist,
disallowApps: proxyServer.configuration.appBlacklist);
},
onStop: () => Vpn.stopVpn())),
);
Expand Down
9 changes: 7 additions & 2 deletions lib/ui/mobile/request/request.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:network_proxy/network/bin/server.dart';
import 'package:network_proxy/network/host_port.dart';
import 'package:network_proxy/network/http/http.dart';
import 'package:network_proxy/network/http_client.dart';
import 'package:network_proxy/network/util/cache.dart';
import 'package:network_proxy/storage/favorites.dart';
import 'package:network_proxy/ui/component/utils.dart';
import 'package:network_proxy/ui/content/panel.dart';
Expand Down Expand Up @@ -42,6 +43,8 @@ class RequestRow extends StatefulWidget {
}

class RequestRowState extends State<RequestRow> {
static ExpiringCache<String, Image> imageCache = ExpiringCache<String, Image>(const Duration(minutes: 5));

late HttpRequest request;
HttpResponse? response;
bool selected = false;
Expand Down Expand Up @@ -114,8 +117,10 @@ class RequestRowState extends State<RequestRow> {
}

//如果有缓存图标直接返回图标
if(request.processInfo!.hasCacheIcon){
return Image.memory(request.processInfo!.cacheIcon!, width: 40);
if (request.processInfo!.hasCacheIcon) {
return imageCache.putIfAbsent(request.processInfo!.id, () {
return Image.memory(request.processInfo!.cacheIcon!, width: 40, gaplessPlayback: true);
});
}

return FutureBuilder(
Expand Down
Loading

0 comments on commit 7452a8f

Please sign in to comment.