add black/white list
This commit is contained in:
15 files changed
+464
-26
No files matched your search
@@ -1,10 +1,66 @@
|
||||
package com.github.kr328.clash
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.*
|
||||
import android.widget.CheckBox
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.kr328.clash.service.ClashSettingService
|
||||
import kotlinx.android.synthetic.main.activity_setting_access.*
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
class SettingAccessActivity : BaseActivity() {
|
||||
private data class AppInfo(val packageName: String, val name: String, val icon: Drawable)
|
||||
|
||||
private class AppListAdapter(val context: Context):
|
||||
RecyclerView.Adapter<AppListAdapter.Holder>() {
|
||||
|
||||
var applications: List<AppInfo> = emptyList()
|
||||
var selected: MutableSet<String> = mutableSetOf()
|
||||
|
||||
class Holder(val view: View) : RecyclerView.ViewHolder(view) {
|
||||
val name: TextView = view.findViewById(R.id.adapter_access_app_name)
|
||||
val packageName: TextView = view.findViewById(R.id.adapter_access_app_package_name)
|
||||
val icon: ImageView = view.findViewById(R.id.adapter_access_app_icon)
|
||||
val checkbox: CheckBox = view.findViewById(R.id.adapter_access_app_checkbox)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
|
||||
return Holder(LayoutInflater.from(context)
|
||||
.inflate(R.layout.adapter_access_app, parent, false))
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return applications.size
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: Holder, position: Int) {
|
||||
val current = applications[position]
|
||||
|
||||
holder.name.text = current.name
|
||||
holder.packageName.text = current.packageName
|
||||
holder.icon.setImageDrawable(current.icon)
|
||||
holder.checkbox.isChecked = current.packageName in selected
|
||||
|
||||
holder.view.setOnClickListener {
|
||||
if ( holder.checkbox.isChecked )
|
||||
selected.remove(current.packageName)
|
||||
else
|
||||
selected.add(current.packageName)
|
||||
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var showList: Boolean = false
|
||||
private var listLoaded: Boolean = false
|
||||
private var hidden: Boolean = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_setting_access)
|
||||
@@ -16,8 +72,9 @@ class SettingAccessActivity : BaseActivity() {
|
||||
activity_setting_access_allow.isChecked = false
|
||||
activity_setting_access_disallow.isChecked = false
|
||||
|
||||
activity_setting_access_divider.visibility = View.GONE
|
||||
activity_setting_access_app_list.visibility = View.GONE
|
||||
showList = false
|
||||
|
||||
updateListStatus()
|
||||
}
|
||||
|
||||
activity_setting_access_allow.setOnClickListener {
|
||||
@@ -25,8 +82,9 @@ class SettingAccessActivity : BaseActivity() {
|
||||
activity_setting_access_allow.isChecked = true
|
||||
activity_setting_access_disallow.isChecked = false
|
||||
|
||||
activity_setting_access_divider.visibility = View.VISIBLE
|
||||
activity_setting_access_app_list.visibility = View.VISIBLE
|
||||
showList = true
|
||||
|
||||
updateListStatus()
|
||||
}
|
||||
|
||||
activity_setting_access_disallow.setOnClickListener {
|
||||
@@ -34,8 +92,175 @@ class SettingAccessActivity : BaseActivity() {
|
||||
activity_setting_access_allow.isChecked = false
|
||||
activity_setting_access_disallow.isChecked = true
|
||||
|
||||
activity_setting_access_divider.visibility = View.VISIBLE
|
||||
activity_setting_access_app_list.visibility = View.VISIBLE
|
||||
showList = true
|
||||
|
||||
updateListStatus()
|
||||
}
|
||||
|
||||
activity_setting_access_app_list.apply {
|
||||
adapter = AppListAdapter(this@SettingAccessActivity)
|
||||
layoutManager = LinearLayoutManager(this@SettingAccessActivity)
|
||||
isNestedScrollingEnabled = false
|
||||
}
|
||||
|
||||
runClash {
|
||||
val settings = it.settingService
|
||||
|
||||
runOnUiThread {
|
||||
when ( settings.accessControlMode ) {
|
||||
ClashSettingService.ACCESS_CONTROL_MODE_ALLOW_ALL ->
|
||||
activity_setting_access_allow_all.performClick()
|
||||
ClashSettingService.ACCESS_CONTROL_MODE_ALLOW ->
|
||||
activity_setting_access_allow.performClick()
|
||||
ClashSettingService.ACCESS_CONTROL_MODE_DISALLOW ->
|
||||
activity_setting_access_disallow.performClick()
|
||||
}
|
||||
}
|
||||
|
||||
val exclude = resources.getStringArray(R.array.default_disallow_application).toSet()
|
||||
|
||||
val applications = packageManager.getInstalledApplications(0)
|
||||
.filterNot {
|
||||
exclude.contains(it.packageName)
|
||||
}
|
||||
.map { app ->
|
||||
AppInfo(app.packageName,
|
||||
app.loadLabel(packageManager).toString(),
|
||||
app.loadIcon(packageManager))
|
||||
}
|
||||
.sortedBy { app ->
|
||||
app.name
|
||||
}
|
||||
val selected = settings.accessControlApps.toMutableSet()
|
||||
|
||||
runOnUiThread {
|
||||
activity_setting_access_app_list.apply {
|
||||
(adapter as AppListAdapter).apply {
|
||||
this.applications = applications
|
||||
this.selected = selected
|
||||
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
listLoaded = true
|
||||
|
||||
updateListStatus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
|
||||
runClash {
|
||||
val mode = when {
|
||||
activity_setting_access_allow_all.isChecked ->
|
||||
ClashSettingService.ACCESS_CONTROL_MODE_ALLOW_ALL
|
||||
activity_setting_access_allow.isChecked ->
|
||||
ClashSettingService.ACCESS_CONTROL_MODE_ALLOW
|
||||
activity_setting_access_disallow.isChecked ->
|
||||
ClashSettingService.ACCESS_CONTROL_MODE_DISALLOW
|
||||
else -> return@runClash
|
||||
}
|
||||
|
||||
if ( listLoaded )
|
||||
it.settingService.setAccessControl(mode,
|
||||
(activity_setting_access_app_list.adapter as AppListAdapter)
|
||||
.selected.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_setting_access, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when ( item.itemId ) {
|
||||
R.id.menu_setting_access_hide -> {
|
||||
if ( hidden ) {
|
||||
activity_setting_access_allow_all.visibility = View.VISIBLE
|
||||
activity_setting_access_allow.visibility = View.VISIBLE
|
||||
activity_setting_access_disallow.visibility = View.VISIBLE
|
||||
|
||||
item.title = getString(R.string.access_setting_hide_header)
|
||||
|
||||
hidden = false
|
||||
}
|
||||
else {
|
||||
if ( !activity_setting_access_allow_all.isChecked )
|
||||
activity_setting_access_allow_all.visibility = View.GONE
|
||||
if ( !activity_setting_access_allow.isChecked )
|
||||
activity_setting_access_allow.visibility = View.GONE
|
||||
if ( !activity_setting_access_disallow.isChecked )
|
||||
activity_setting_access_disallow.visibility = View.GONE
|
||||
|
||||
item.title = getString(R.string.access_setting_show_header)
|
||||
|
||||
hidden = true
|
||||
}
|
||||
}
|
||||
R.id.menu_setting_access_select_all -> {
|
||||
thread {
|
||||
val selected = (activity_setting_access_app_list.adapter as AppListAdapter)
|
||||
.applications.map { it.packageName }.toMutableSet()
|
||||
|
||||
runOnUiThread {
|
||||
(activity_setting_access_app_list.adapter as AppListAdapter).apply {
|
||||
this.selected = selected
|
||||
|
||||
notifyItemRangeChanged(0, applications.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
R.id.menu_setting_access_select_invert -> {
|
||||
thread {
|
||||
(activity_setting_access_app_list.adapter as AppListAdapter).apply {
|
||||
selected = (applications.map { it.packageName }.toSet() - selected).toMutableSet()
|
||||
}
|
||||
|
||||
runOnUiThread {
|
||||
(activity_setting_access_app_list.adapter as AppListAdapter).apply {
|
||||
notifyItemRangeChanged(0, applications.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
R.id.menu_setting_access_clean_selection -> {
|
||||
(activity_setting_access_app_list.adapter as AppListAdapter).apply {
|
||||
selected = mutableSetOf()
|
||||
|
||||
notifyItemRangeChanged(0, applications.size)
|
||||
}
|
||||
}
|
||||
else -> return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun updateListStatus() {
|
||||
if ( showList )
|
||||
activity_setting_access_divider.visibility = View.VISIBLE
|
||||
else
|
||||
activity_setting_access_divider.visibility = View.GONE
|
||||
|
||||
|
||||
if ( showList ) {
|
||||
if ( listLoaded )
|
||||
activity_setting_access_loading.visibility = View.GONE
|
||||
else
|
||||
activity_setting_access_loading.visibility = View.VISIBLE
|
||||
}
|
||||
else
|
||||
activity_setting_access_loading.visibility = View.GONE
|
||||
|
||||
|
||||
if ( showList && listLoaded )
|
||||
activity_setting_access_app_list.visibility = View.VISIBLE
|
||||
else
|
||||
activity_setting_access_app_list.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
@@ -69,6 +69,12 @@ class RadioFatItem @JvmOverloads constructor(
|
||||
operationClickable.setOnLongClickListener(l)
|
||||
}
|
||||
|
||||
override fun performClick(): Boolean {
|
||||
super.performClick()
|
||||
|
||||
return clickable.performClick()
|
||||
}
|
||||
|
||||
init {
|
||||
with(LayoutInflater.from(context).inflate(R.layout.view_radio_fat_item, this, true)) {
|
||||
titleView = findViewById(R.id.view_radio_fat_item_title)
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
android:layout_height="60dp" />
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
|
||||
|
||||
<com.github.kr328.clash.view.RadioFatItem
|
||||
app:title="@string/access_setting_allow_all"
|
||||
app:summary="@string/access_setting_allow_all_summary"
|
||||
@@ -45,8 +47,18 @@
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/lightGray"/>
|
||||
|
||||
<ListView
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/activity_setting_access_app_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/activity_setting_access_loading"
|
||||
android:text="@string/access_setting_loading"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginStart="70dp"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_marginTop="5dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="70dp"
|
||||
android:focusable="true"
|
||||
android:clickable="true"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/adapter_access_app_icon"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:contentDescription="@string/app_name" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toEndOf="@+id/adapter_access_app_icon"
|
||||
android:layout_toStartOf="@id/adapter_access_app_checkbox"
|
||||
android:layout_centerVertical="true"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:id="@+id/adapter_access_app_name"
|
||||
android:textColor="@android:color/black"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
<TextView
|
||||
android:id="@+id/adapter_access_app_package_name"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.checkbox.MaterialCheckBox
|
||||
android:id="@+id/adapter_access_app_checkbox"
|
||||
android:focusable="false"
|
||||
android:clickable="false"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:gravity="center"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="70dp"/>
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_setting_access_hide"
|
||||
android:title="@string/access_setting_hide_header" />
|
||||
<item
|
||||
android:id="@+id/menu_setting_access_select_all"
|
||||
android:title="@string/access_setting_select_all" />
|
||||
<item
|
||||
android:id="@+id/menu_setting_access_select_invert"
|
||||
android:title="@string/access_setting_select_invert" />
|
||||
<item
|
||||
android:id="@+id/menu_setting_access_clean_selection"
|
||||
android:title="@string/access_setting_clean_selection" />
|
||||
</menu>
|
||||
@@ -64,4 +64,10 @@
|
||||
<string name="access_setting_allow_summary">Allow follow apps access vpn</string>
|
||||
<string name="access_setting_disallow">Disallow</string>
|
||||
<string name="access_setting_disallow_summary">Disallow follow apps access vpn</string>
|
||||
<string name="access_setting_loading">Loading</string>
|
||||
<string name="access_setting_show_header">Show Header</string>
|
||||
<string name="access_setting_hide_header">Hide Header</string>
|
||||
<string name="access_setting_select_all">Select All</string>
|
||||
<string name="access_setting_select_invert">Select Invert</string>
|
||||
<string name="access_setting_clean_selection">Clear Selection</string>
|
||||
</resources>
|
||||
Submodule core/src/main/golang/clash updated: f0f6d92a2b...d5d22cce0c.
@@ -26,8 +26,11 @@ android {
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
targetCompatibility = 1.8
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.github.kr328.clash.service;
|
||||
import com.github.kr328.clash.service.IClashEventObserver;
|
||||
import com.github.kr328.clash.service.IClashEventService;
|
||||
import com.github.kr328.clash.service.IClashProfileService;
|
||||
import com.github.kr328.clash.service.IClashSettingService;
|
||||
import com.github.kr328.clash.core.event.Event;
|
||||
import com.github.kr328.clash.core.model.ProxyPacket;
|
||||
|
||||
@@ -10,6 +11,7 @@ interface IClashService {
|
||||
// Services
|
||||
IClashEventService getEventService();
|
||||
IClashProfileService getProfileService();
|
||||
IClashSettingService getSettingService();
|
||||
|
||||
// Status
|
||||
ProcessEvent getCurrentProcessStatus();
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.github.kr328.clash.service;
|
||||
|
||||
interface IClashSettingService {
|
||||
// Set
|
||||
void setIPv6Enabled(boolean enabled);
|
||||
void setBypassPrivateNetwork(boolean enabled);
|
||||
void setAccessControl(int mode, in String[] applications);
|
||||
|
||||
// Get
|
||||
boolean isIPv6Enabled();
|
||||
boolean isBypassPrivateNetwork();
|
||||
String[] getAccessControlApps();
|
||||
int getAccessControlMode();
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import com.github.kr328.clash.core.Clash
|
||||
import com.github.kr328.clash.core.event.*
|
||||
import com.github.kr328.clash.core.model.ProxyPacket
|
||||
import com.github.kr328.clash.core.utils.Log
|
||||
import com.github.kr328.clash.service.data.ClashDatabase
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.Executors
|
||||
@@ -24,6 +23,7 @@ class ClashService : Service(), IClashEventObserver, ClashEventService.Master,
|
||||
|
||||
private val eventService = ClashEventService(this)
|
||||
private val profileService = ClashProfileService(this, this)
|
||||
private val settingService = ClashSettingService(this)
|
||||
|
||||
private lateinit var clash: Clash
|
||||
private lateinit var puller: ClashEventPuller
|
||||
@@ -103,6 +103,10 @@ class ClashService : Service(), IClashEventObserver, ClashEventService.Master,
|
||||
return this@ClashService.profileService
|
||||
}
|
||||
|
||||
override fun getSettingService(): IClashSettingService {
|
||||
return this@ClashService.settingService
|
||||
}
|
||||
|
||||
override fun getCurrentProcessStatus(): ProcessEvent {
|
||||
return clash.process.getProcessStatus()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.github.kr328.clash.service
|
||||
|
||||
import android.content.Context
|
||||
import androidx.core.content.edit
|
||||
|
||||
class ClashSettingService(context: Context): IClashSettingService.Stub() {
|
||||
companion object {
|
||||
const val KEY_ACCESS_CONTROL_MODE = "key_access_control_mode"
|
||||
const val KEY_ACCESS_CONTROL_APPS = "ley_access_control_apps"
|
||||
const val KEY_IPV6_ENABLED = "key_ipv6_enabled"
|
||||
const val KEY_BYPASS_PRIVATE_NETWORK = "key_bypass_private_network"
|
||||
|
||||
const val ACCESS_CONTROL_MODE_ALLOW_ALL = 0
|
||||
const val ACCESS_CONTROL_MODE_ALLOW = 1
|
||||
const val ACCESS_CONTROL_MODE_DISALLOW = 2
|
||||
}
|
||||
|
||||
private val preference by lazy {
|
||||
context.getSharedPreferences("clash_service", Context.MODE_PRIVATE)
|
||||
}
|
||||
|
||||
override fun setAccessControl(mode: Int, applications: Array<out String>?) {
|
||||
require(mode in 0..3)
|
||||
|
||||
preference.edit {
|
||||
putInt(KEY_ACCESS_CONTROL_MODE, mode)
|
||||
putStringSet(KEY_ACCESS_CONTROL_APPS, applications?.toSet() ?: emptySet())
|
||||
}
|
||||
}
|
||||
|
||||
override fun setIPv6Enabled(enabled: Boolean) {
|
||||
preference.edit {
|
||||
putBoolean(KEY_IPV6_ENABLED, enabled)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setBypassPrivateNetwork(enabled: Boolean) {
|
||||
preference.edit {
|
||||
putBoolean(KEY_BYPASS_PRIVATE_NETWORK, enabled)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isBypassPrivateNetwork(): Boolean {
|
||||
return preference.getBoolean(KEY_BYPASS_PRIVATE_NETWORK, true)
|
||||
}
|
||||
|
||||
override fun isIPv6Enabled(): Boolean {
|
||||
return preference.getBoolean(KEY_IPV6_ENABLED, true)
|
||||
}
|
||||
|
||||
override fun getAccessControlApps(): Array<String> {
|
||||
return preference.getStringSet(KEY_ACCESS_CONTROL_APPS, emptySet())?.toTypedArray()!!
|
||||
}
|
||||
|
||||
override fun getAccessControlMode(): Int {
|
||||
return preference.getInt(KEY_ACCESS_CONTROL_MODE, ACCESS_CONTROL_MODE_ALLOW_ALL)
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import android.content.ServiceConnection
|
||||
import android.net.VpnService
|
||||
import android.os.*
|
||||
import com.github.kr328.clash.core.event.*
|
||||
import com.github.kr328.clash.core.utils.Log
|
||||
import com.github.kr328.clash.service.net.DefaultNetworkObserver
|
||||
|
||||
class TunService : VpnService(), IClashEventObserver {
|
||||
@@ -23,6 +24,7 @@ class TunService : VpnService(), IClashEventObserver {
|
||||
private lateinit var fileDescriptor: ParcelFileDescriptor
|
||||
private lateinit var clash: IClashService
|
||||
private lateinit var defaultNetworkObserver: DefaultNetworkObserver
|
||||
private lateinit var settings: ClashSettingService
|
||||
private val connection = object : ServiceConnection {
|
||||
override fun onServiceDisconnected(name: ComponentName?) {
|
||||
stopSelf()
|
||||
@@ -53,9 +55,10 @@ class TunService : VpnService(), IClashEventObserver {
|
||||
return
|
||||
}
|
||||
|
||||
settings = ClashSettingService(this)
|
||||
|
||||
fileDescriptor = Builder()
|
||||
.addAddress(PRIVATE_VLAN4_CLIENT, 30)
|
||||
.addAddress(PRIVATE_VLAN6_CLIENT, 126)
|
||||
.addAddress()
|
||||
.addDnsServer(PRIVATE_DEFAULT_DNS)
|
||||
.addBypassApplications()
|
||||
.addBypassPrivateRoute()
|
||||
@@ -120,22 +123,65 @@ class TunService : VpnService(), IClashEventObserver {
|
||||
|
||||
private fun Builder.addBypassPrivateRoute(): Builder {
|
||||
// IPv4
|
||||
resources.getStringArray(R.array.bypass_private_route).forEach {
|
||||
val address = it.split("/")
|
||||
addRoute(address[0], address[1].toInt())
|
||||
if ( settings.isBypassPrivateNetwork ) {
|
||||
resources.getStringArray(R.array.bypass_private_route).forEach {
|
||||
val address = it.split("/")
|
||||
addRoute(address[0], address[1].toInt())
|
||||
}
|
||||
}
|
||||
else {
|
||||
addRoute("0.0.0.0", 0)
|
||||
}
|
||||
|
||||
// IPv6
|
||||
addRoute("::", 0)
|
||||
if ( settings.isIPv6Enabled ) {
|
||||
|
||||
addRoute("::", 0)
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
private fun Builder.addBypassApplications(): Builder {
|
||||
resources.getStringArray(R.array.default_bypass_application)
|
||||
.forEach {
|
||||
runCatching { this.addDisallowedApplication(it) }
|
||||
when ( settings.accessControlMode ) {
|
||||
ClashSettingService.ACCESS_CONTROL_MODE_ALLOW_ALL -> {
|
||||
for ( app in resources.getStringArray(R.array.default_disallow_application) ) {
|
||||
runCatching {
|
||||
addDisallowedApplication(app)
|
||||
}
|
||||
}
|
||||
}
|
||||
ClashSettingService.ACCESS_CONTROL_MODE_ALLOW -> {
|
||||
for ( app in (settings.accessControlApps.toSet() -
|
||||
resources.getStringArray(R.array.default_disallow_application)) ) {
|
||||
runCatching {
|
||||
addAllowedApplication(app)
|
||||
}.onFailure {
|
||||
Log.w("Package $app not found")
|
||||
}
|
||||
}
|
||||
}
|
||||
ClashSettingService.ACCESS_CONTROL_MODE_DISALLOW -> {
|
||||
for ( app in (settings.accessControlApps.toSet() +
|
||||
resources.getStringArray(R.array.default_disallow_application)) ) {
|
||||
runCatching {
|
||||
addDisallowedApplication(app)
|
||||
}.onFailure {
|
||||
Log.w("Package $app not found")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
private fun Builder.addAddress(): Builder {
|
||||
addAddress(PRIVATE_VLAN4_CLIENT, 30)
|
||||
|
||||
if ( settings.isIPv6Enabled )
|
||||
addAddress(PRIVATE_VLAN6_CLIENT, 126)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -1,11 +1,9 @@
|
||||
package com.github.kr328.clash.service.data
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
import androidx.room.*
|
||||
|
||||
@Entity(tableName = "profile_select_proxies",
|
||||
indices = [Index("profile_id")],
|
||||
foreignKeys = [ForeignKey(entity = ClashProfileEntity::class,
|
||||
childColumns = ["profile_id"],
|
||||
parentColumns = ["id"],
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
<item>224.0.0.0/3</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="default_bypass_application">
|
||||
<string-array name="default_disallow_application">
|
||||
<item>com.github.kr328.clash</item>
|
||||
<item>com.android.networkstack</item>
|
||||
</string-array>
|
||||
|
||||
Reference in new issue
Block a user