mirror of
				https://github.com/yggdrasil-network/yggdrasil-android.git
				synced 2025-11-04 11:15:08 +03:00 
			
		
		
		
	Added DNS configuration functionality.
This commit is contained in:
		
							parent
							
								
									80fc552603
								
							
						
					
					
						commit
						dd67347cd8
					
				
					 14 changed files with 369 additions and 25 deletions
				
			
		| 
						 | 
				
			
			@ -39,6 +39,7 @@ dependencies {
 | 
			
		|||
    implementation 'androidx.appcompat:appcompat:1.3.0'
 | 
			
		||||
    implementation 'com.google.android.material:material:1.3.0'
 | 
			
		||||
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
 | 
			
		||||
    implementation 'androidx.preference:preference-ktx:1.1.0'
 | 
			
		||||
    testImplementation 'junit:junit:4.+'
 | 
			
		||||
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
 | 
			
		||||
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,17 +16,19 @@
 | 
			
		|||
            android:parentActivityName=".MainActivity" />
 | 
			
		||||
        <activity android:name=".PeersActivity"
 | 
			
		||||
            android:parentActivityName=".MainActivity" />
 | 
			
		||||
        <activity android:name=".MainActivity">
 | 
			
		||||
        <activity android:name=".MainActivity" android:exported="true">
 | 
			
		||||
            <intent-filter>
 | 
			
		||||
                <action android:name="android.intent.action.MAIN" />
 | 
			
		||||
 | 
			
		||||
                <category android:name="android.intent.category.LAUNCHER" />
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
        </activity>
 | 
			
		||||
        <activity android:name=".DnsActivity" android:exported="false" />
 | 
			
		||||
 | 
			
		||||
        <service
 | 
			
		||||
            android:name=".PacketTunnelProvider"
 | 
			
		||||
            android:permission="android.permission.BIND_VPN_SERVICE">
 | 
			
		||||
            android:permission="android.permission.BIND_VPN_SERVICE"
 | 
			
		||||
            android:exported="true">
 | 
			
		||||
            <intent-filter>
 | 
			
		||||
                <action android:name="android.net.VpnService" />
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										114
									
								
								app/src/main/java/eu/neilalexander/yggdrasil/DnsActivity.kt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								app/src/main/java/eu/neilalexander/yggdrasil/DnsActivity.kt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,114 @@
 | 
			
		|||
package eu.neilalexander.yggdrasil
 | 
			
		||||
 | 
			
		||||
import android.annotation.SuppressLint
 | 
			
		||||
import android.app.AlertDialog
 | 
			
		||||
import android.content.SharedPreferences
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.view.ContextThemeWrapper
 | 
			
		||||
import android.view.LayoutInflater
 | 
			
		||||
import android.view.View
 | 
			
		||||
import android.widget.*
 | 
			
		||||
import com.google.android.material.textfield.TextInputEditText
 | 
			
		||||
 | 
			
		||||
const val KEY_DNS_SERVERS = "dns_servers"
 | 
			
		||||
const val DEFAULT_DNS_SERVERS = "302:7991::53,302:db60::53,300:6223::53"
 | 
			
		||||
 | 
			
		||||
class DnsActivity : AppCompatActivity() {
 | 
			
		||||
    private lateinit var config: ConfigurationProxy
 | 
			
		||||
    private lateinit var inflater: LayoutInflater
 | 
			
		||||
 | 
			
		||||
    private lateinit var serversTableLayout: TableLayout
 | 
			
		||||
    private lateinit var serversTableLabel: TextView
 | 
			
		||||
    private lateinit var addServerButton: ImageButton
 | 
			
		||||
    private lateinit var servers: MutableList<String>
 | 
			
		||||
    private lateinit var preferences: SharedPreferences
 | 
			
		||||
 | 
			
		||||
    @SuppressLint("ApplySharedPref")
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        super.onCreate(savedInstanceState)
 | 
			
		||||
        setContentView(R.layout.activity_dns)
 | 
			
		||||
 | 
			
		||||
        config = ConfigurationProxy(applicationContext)
 | 
			
		||||
        inflater = LayoutInflater.from(this)
 | 
			
		||||
 | 
			
		||||
        serversTableLayout = findViewById(R.id.configuredDnsTableLayout)
 | 
			
		||||
        serversTableLabel = findViewById(R.id.configuredDnsLabel)
 | 
			
		||||
 | 
			
		||||
        addServerButton = findViewById(R.id.addServerButton)
 | 
			
		||||
        addServerButton.setOnClickListener {
 | 
			
		||||
            val view = inflater.inflate(R.layout.dialog_add_dns_server, null)
 | 
			
		||||
            val input = view.findViewById<TextInputEditText>(R.id.addDnsInput)
 | 
			
		||||
            val builder: AlertDialog.Builder = AlertDialog.Builder(ContextThemeWrapper(this, R.style.Theme_MaterialComponents_DayNight_Dialog))
 | 
			
		||||
            builder.setTitle("Add DNS server")
 | 
			
		||||
            builder.setView(view)
 | 
			
		||||
            builder.setPositiveButton("Add") { dialog, _ ->
 | 
			
		||||
                servers.add(input.text.toString())
 | 
			
		||||
                preferences.edit().apply {
 | 
			
		||||
                    this.putString(KEY_DNS_SERVERS, servers.joinToString(","))
 | 
			
		||||
                    this.commit()
 | 
			
		||||
                }
 | 
			
		||||
                dialog.dismiss()
 | 
			
		||||
                updateConfiguredServers()
 | 
			
		||||
            }
 | 
			
		||||
            builder.setNegativeButton("Cancel") { dialog, _ ->
 | 
			
		||||
                dialog.cancel()
 | 
			
		||||
            }
 | 
			
		||||
            builder.show()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        preferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this.baseContext)
 | 
			
		||||
        val serverString = preferences.getString(KEY_DNS_SERVERS, DEFAULT_DNS_SERVERS)
 | 
			
		||||
        if (serverString!!.isNotEmpty()) {
 | 
			
		||||
            servers = serverString.split(",").toMutableList()
 | 
			
		||||
        } else {
 | 
			
		||||
            servers = mutableListOf()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onResume() {
 | 
			
		||||
        super.onResume()
 | 
			
		||||
        updateConfiguredServers()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressLint("ApplySharedPref")
 | 
			
		||||
    private fun updateConfiguredServers() {
 | 
			
		||||
        when (servers.size) {
 | 
			
		||||
            0 -> {
 | 
			
		||||
                serversTableLayout.visibility = View.GONE
 | 
			
		||||
                serversTableLabel.text = "No servers configured"
 | 
			
		||||
            }
 | 
			
		||||
            else -> {
 | 
			
		||||
                serversTableLayout.visibility = View.VISIBLE
 | 
			
		||||
                serversTableLabel.text = "Configured servers"
 | 
			
		||||
 | 
			
		||||
                serversTableLayout.removeAllViewsInLayout()
 | 
			
		||||
                for (i in servers.indices) {
 | 
			
		||||
                    val peer = servers[i]
 | 
			
		||||
                    val view = inflater.inflate(R.layout.peers_configured, null)
 | 
			
		||||
                    view.findViewById<TextView>(R.id.addressValue).text = peer
 | 
			
		||||
                    view.findViewById<ImageButton>(R.id.deletePeerButton).tag = i
 | 
			
		||||
 | 
			
		||||
                    view.findViewById<ImageButton>(R.id.deletePeerButton).setOnClickListener { button ->
 | 
			
		||||
                        val builder: AlertDialog.Builder = AlertDialog.Builder(this)
 | 
			
		||||
                        builder.setTitle("Remove ${peer}?")
 | 
			
		||||
                        builder.setPositiveButton("Remove") { dialog, _ ->
 | 
			
		||||
                            servers.removeAt(button.tag as Int)
 | 
			
		||||
                            preferences.edit().apply {
 | 
			
		||||
                                this.putString(KEY_DNS_SERVERS, servers.joinToString(","))
 | 
			
		||||
                                this.commit()
 | 
			
		||||
                            }
 | 
			
		||||
                            dialog.dismiss()
 | 
			
		||||
                            updateConfiguredServers()
 | 
			
		||||
                        }
 | 
			
		||||
                        builder.setNegativeButton("Cancel") { dialog, _ ->
 | 
			
		||||
                            dialog.cancel()
 | 
			
		||||
                        }
 | 
			
		||||
                        builder.show()
 | 
			
		||||
                    }
 | 
			
		||||
                    serversTableLayout.addView(view)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -27,6 +27,8 @@ class MainActivity : AppCompatActivity() {
 | 
			
		|||
    private lateinit var coordinatesLabel: TextView
 | 
			
		||||
    private lateinit var peersLabel: TextView
 | 
			
		||||
    private lateinit var peersRow: TableRow
 | 
			
		||||
    private lateinit var dnsLabel: TextView
 | 
			
		||||
    private lateinit var dnsRow: TableRow
 | 
			
		||||
    private lateinit var settingsRow: TableRow
 | 
			
		||||
 | 
			
		||||
    private fun start() {
 | 
			
		||||
| 
						 | 
				
			
			@ -47,13 +49,15 @@ class MainActivity : AppCompatActivity() {
 | 
			
		|||
 | 
			
		||||
        findViewById<TextView>(R.id.versionValue).text = Mobile.getVersion()
 | 
			
		||||
 | 
			
		||||
        enabledSwitch = findViewById(R.id.enableMulticastBeacon)
 | 
			
		||||
        enabledSwitch = findViewById(R.id.enableYggdrasil)
 | 
			
		||||
        enabledLabel = findViewById(R.id.yggdrasilStatusLabel)
 | 
			
		||||
        ipAddressLabel = findViewById(R.id.ipAddressValue)
 | 
			
		||||
        subnetLabel = findViewById(R.id.subnetValue)
 | 
			
		||||
        coordinatesLabel = findViewById(R.id.coordinatesValue)
 | 
			
		||||
        peersLabel = findViewById(R.id.peersValue)
 | 
			
		||||
        peersRow = findViewById(R.id.peersTableRow)
 | 
			
		||||
        dnsLabel = findViewById(R.id.dnsValue)
 | 
			
		||||
        dnsRow = findViewById(R.id.dnsTableRow)
 | 
			
		||||
        settingsRow = findViewById(R.id.settingsTableRow)
 | 
			
		||||
 | 
			
		||||
        enabledLabel.setTextColor(Color.GRAY)
 | 
			
		||||
| 
						 | 
				
			
			@ -82,6 +86,12 @@ class MainActivity : AppCompatActivity() {
 | 
			
		|||
            startActivity(intent)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        dnsRow.isClickable = true
 | 
			
		||||
        dnsRow.setOnClickListener {
 | 
			
		||||
            val intent = Intent(this, DnsActivity::class.java)
 | 
			
		||||
            startActivity(intent)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        settingsRow.isClickable = true
 | 
			
		||||
        settingsRow.setOnClickListener {
 | 
			
		||||
            val intent = Intent(this, SettingsActivity::class.java)
 | 
			
		||||
| 
						 | 
				
			
			@ -94,6 +104,18 @@ class MainActivity : AppCompatActivity() {
 | 
			
		|||
        LocalBroadcastManager.getInstance(this).registerReceiver(
 | 
			
		||||
            receiver, IntentFilter(PacketTunnelState.RECEIVER_INTENT)
 | 
			
		||||
        )
 | 
			
		||||
        val preferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this.baseContext)
 | 
			
		||||
        val serverString = preferences.getString(KEY_DNS_SERVERS, DEFAULT_DNS_SERVERS)
 | 
			
		||||
        if (serverString!!.isNotEmpty()) {
 | 
			
		||||
            val servers = serverString.split(",")
 | 
			
		||||
            dnsLabel.text = when (servers.size) {
 | 
			
		||||
                0 -> "No servers"
 | 
			
		||||
                1 -> "1 server"
 | 
			
		||||
                else -> "${servers.size} servers"
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            dnsLabel.text = "No servers"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private val receiver: BroadcastReceiver = object : BroadcastReceiver() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,6 +17,8 @@ import java.util.concurrent.atomic.AtomicBoolean
 | 
			
		|||
import kotlin.concurrent.thread
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
private const val TAG = "PacketTunnelProvider"
 | 
			
		||||
 | 
			
		||||
class PacketTunnelProvider: VpnService() {
 | 
			
		||||
    companion object {
 | 
			
		||||
        const val RECEIVER_INTENT = "eu.neilalexander.yggdrasil.PacketTunnelProvider.MESSAGE"
 | 
			
		||||
| 
						 | 
				
			
			@ -50,16 +52,16 @@ class PacketTunnelProvider: VpnService() {
 | 
			
		|||
 | 
			
		||||
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
 | 
			
		||||
        if (intent == null) {
 | 
			
		||||
            Log.d("PacketTunnelProvider", "Intent is null")
 | 
			
		||||
            Log.d(TAG, "Intent is null")
 | 
			
		||||
            return START_NOT_STICKY
 | 
			
		||||
        }
 | 
			
		||||
        return when (intent.action ?: ACTION_STOP) {
 | 
			
		||||
            ACTION_STOP -> {
 | 
			
		||||
                Log.d("PacketTunnelProvider", "Stopping...")
 | 
			
		||||
                Log.d(TAG, "Stopping...")
 | 
			
		||||
                stop(); START_NOT_STICKY
 | 
			
		||||
            }
 | 
			
		||||
            else -> {
 | 
			
		||||
                Log.d("PacketTunnelProvider", "Starting...")
 | 
			
		||||
                Log.d(TAG, "Starting...")
 | 
			
		||||
                start(); START_STICKY
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -70,11 +72,11 @@ class PacketTunnelProvider: VpnService() {
 | 
			
		|||
            return
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Log.d("PacketTunnelProvider", config.getJSON().toString())
 | 
			
		||||
        Log.d(TAG, config.getJSON().toString())
 | 
			
		||||
        yggdrasil.startJSON(config.getJSONByteArray())
 | 
			
		||||
 | 
			
		||||
        val address = yggdrasil.addressString
 | 
			
		||||
        var builder = Builder()
 | 
			
		||||
        val builder = Builder()
 | 
			
		||||
            .addAddress(address, 7)
 | 
			
		||||
            .addRoute("200::", 7)
 | 
			
		||||
            // We do this to trick the DNS-resolver into thinking that we have "regular" IPv6,
 | 
			
		||||
| 
						 | 
				
			
			@ -97,6 +99,18 @@ class PacketTunnelProvider: VpnService() {
 | 
			
		|||
            builder.setMetered(false)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        val preferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this.baseContext)
 | 
			
		||||
        val serverString = preferences.getString(KEY_DNS_SERVERS, DEFAULT_DNS_SERVERS)
 | 
			
		||||
        if (serverString!!.isNotEmpty()) {
 | 
			
		||||
            val servers = serverString.split(",")
 | 
			
		||||
            if (servers.isNotEmpty()) {
 | 
			
		||||
                servers.forEach {
 | 
			
		||||
                    Log.i(TAG, "Using DNS server $it")
 | 
			
		||||
                    builder.addDnsServer(it)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        parcel = builder.establish()
 | 
			
		||||
        val parcel = parcel
 | 
			
		||||
        if (parcel == null || !parcel.fileDescriptor.valid()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -123,7 +137,7 @@ class PacketTunnelProvider: VpnService() {
 | 
			
		|||
        intent.putExtra("ip", yggdrasil.addressString)
 | 
			
		||||
        intent.putExtra("subnet", yggdrasil.subnetString)
 | 
			
		||||
        intent.putExtra("coords", yggdrasil.coordsString)
 | 
			
		||||
        intent.putExtra("peers", JSONArray(yggdrasil.peersJSON).length())
 | 
			
		||||
        intent.putExtra("peers", yggdrasil.peersJSON)
 | 
			
		||||
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,14 +49,14 @@ class PeersActivity : AppCompatActivity() {
 | 
			
		|||
 | 
			
		||||
        addPeerButton = findViewById(R.id.addPeerButton)
 | 
			
		||||
        addPeerButton.setOnClickListener {
 | 
			
		||||
            var view = inflater.inflate(R.layout.dialog_addpeer, null)
 | 
			
		||||
            var input = view.findViewById<TextInputEditText>(R.id.addPeerInput)
 | 
			
		||||
            val view = inflater.inflate(R.layout.dialog_addpeer, null)
 | 
			
		||||
            val input = view.findViewById<TextInputEditText>(R.id.addPeerInput)
 | 
			
		||||
            val builder: AlertDialog.Builder = AlertDialog.Builder(ContextThemeWrapper(this, R.style.Theme_MaterialComponents_DayNight_Dialog))
 | 
			
		||||
            builder.setTitle("Add Configured Peer")
 | 
			
		||||
            builder.setView(view)
 | 
			
		||||
            builder.setPositiveButton("Add") { dialog, _ ->
 | 
			
		||||
                config.updateJSON { json ->
 | 
			
		||||
                    json.getJSONArray("Peers").put(input.text)
 | 
			
		||||
                    json.getJSONArray("Peers").put(input.text.toString().trim())
 | 
			
		||||
                }
 | 
			
		||||
                dialog.dismiss()
 | 
			
		||||
                updateConfiguredPeers()
 | 
			
		||||
| 
						 | 
				
			
			@ -90,7 +90,7 @@ class PeersActivity : AppCompatActivity() {
 | 
			
		|||
                configuredTableLayout.removeAllViewsInLayout()
 | 
			
		||||
                for (i in 0 until peers.length()) {
 | 
			
		||||
                    val peer = peers[i].toString()
 | 
			
		||||
                    var view = inflater.inflate(R.layout.peers_configured, null)
 | 
			
		||||
                    val view = inflater.inflate(R.layout.peers_configured, null)
 | 
			
		||||
                    view.findViewById<TextView>(R.id.addressValue).text = peer
 | 
			
		||||
                    view.findViewById<ImageButton>(R.id.deletePeerButton).tag = i
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -130,7 +130,7 @@ class PeersActivity : AppCompatActivity() {
 | 
			
		|||
                connectedTableLayout.removeAllViewsInLayout()
 | 
			
		||||
                for (i in 0 until peers.length()) {
 | 
			
		||||
                    val peer = peers.getJSONObject(i)
 | 
			
		||||
                    var view = inflater.inflate(R.layout.peers_connected, null)
 | 
			
		||||
                    val view = inflater.inflate(R.layout.peers_connected, null)
 | 
			
		||||
                    val ip = peer.getString("IP")
 | 
			
		||||
                    view.findViewById<TextView>(R.id.addressLabel).text = ip
 | 
			
		||||
                    view.findViewById<TextView>(R.id.detailsLabel).text = peer.getString("Remote")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										114
									
								
								app/src/main/res/layout/activity_dns.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								app/src/main/res/layout/activity_dns.xml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,114 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    tools:context=".DnsActivity">
 | 
			
		||||
 | 
			
		||||
    <FrameLayout
 | 
			
		||||
        android:id="@+id/settings"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="match_parent">
 | 
			
		||||
 | 
			
		||||
        <LinearLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="match_parent"
 | 
			
		||||
            android:dividerPadding="4pt"
 | 
			
		||||
            android:orientation="vertical">
 | 
			
		||||
 | 
			
		||||
            <LinearLayout
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:orientation="horizontal">
 | 
			
		||||
 | 
			
		||||
                <TextView
 | 
			
		||||
                    android:id="@+id/pageTitle"
 | 
			
		||||
                    android:layout_width="wrap_content"
 | 
			
		||||
                    android:layout_height="wrap_content"
 | 
			
		||||
                    android:layout_margin="8pt"
 | 
			
		||||
                    android:text="DNS"
 | 
			
		||||
                    android:textColor="?attr/textDefault"
 | 
			
		||||
                    android:textSize="24sp"
 | 
			
		||||
                    android:textStyle="bold" />
 | 
			
		||||
 | 
			
		||||
                <Space
 | 
			
		||||
                    android:layout_width="0dp"
 | 
			
		||||
                    android:layout_height="wrap_content"
 | 
			
		||||
                    android:layout_weight="1" />
 | 
			
		||||
 | 
			
		||||
                <ImageButton
 | 
			
		||||
                    android:id="@+id/addServerButton"
 | 
			
		||||
                    android:layout_width="16pt"
 | 
			
		||||
                    android:layout_height="16pt"
 | 
			
		||||
                    android:layout_marginTop="6pt"
 | 
			
		||||
                    android:layout_marginRight="8pt"
 | 
			
		||||
                    android:background="@android:color/transparent"
 | 
			
		||||
                    app:srcCompat="@drawable/ic_baseline_add_circle_24" />
 | 
			
		||||
            </LinearLayout>
 | 
			
		||||
 | 
			
		||||
            <ScrollView
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="match_parent">
 | 
			
		||||
 | 
			
		||||
                <LinearLayout
 | 
			
		||||
                    android:layout_width="match_parent"
 | 
			
		||||
                    android:layout_height="wrap_content"
 | 
			
		||||
                    android:orientation="vertical" >
 | 
			
		||||
 | 
			
		||||
                    <TextView
 | 
			
		||||
                        android:id="@+id/configuredDnsLabel"
 | 
			
		||||
                        android:layout_width="match_parent"
 | 
			
		||||
                        android:layout_height="wrap_content"
 | 
			
		||||
                        android:layout_marginStart="16pt"
 | 
			
		||||
                        android:layout_marginLeft="16pt"
 | 
			
		||||
                        android:layout_marginTop="8pt"
 | 
			
		||||
                        android:layout_marginEnd="8pt"
 | 
			
		||||
                        android:layout_marginRight="8pt"
 | 
			
		||||
                        android:layout_marginBottom="2pt"
 | 
			
		||||
                        android:alpha="0.7"
 | 
			
		||||
                        android:paddingRight="8pt"
 | 
			
		||||
                        android:text="DNS servers"
 | 
			
		||||
                        android:textAllCaps="true"
 | 
			
		||||
                        android:textAppearance="@style/TextAppearance.AppCompat.Small"
 | 
			
		||||
                        android:textSize="12sp" />
 | 
			
		||||
 | 
			
		||||
                    <TableLayout
 | 
			
		||||
                        android:id="@+id/configuredDnsTableLayout"
 | 
			
		||||
                        android:layout_width="match_parent"
 | 
			
		||||
                        android:layout_height="wrap_content"
 | 
			
		||||
                        android:layout_marginStart="8pt"
 | 
			
		||||
                        android:layout_marginLeft="8pt"
 | 
			
		||||
                        android:layout_marginEnd="8pt"
 | 
			
		||||
                        android:layout_marginRight="8pt"
 | 
			
		||||
                        android:background="@drawable/rounded"
 | 
			
		||||
                        android:divider="#46878787"
 | 
			
		||||
                        android:dividerPadding="4pt"
 | 
			
		||||
                        android:paddingLeft="4pt"
 | 
			
		||||
                        android:paddingTop="2pt"
 | 
			
		||||
                        android:paddingRight="4pt"
 | 
			
		||||
                        android:paddingBottom="2pt"
 | 
			
		||||
                        android:showDividers="middle" />
 | 
			
		||||
 | 
			
		||||
                    <TextView
 | 
			
		||||
                        android:layout_width="match_parent"
 | 
			
		||||
                        android:layout_height="wrap_content"
 | 
			
		||||
                        android:layout_marginStart="16pt"
 | 
			
		||||
                        android:layout_marginLeft="16pt"
 | 
			
		||||
                        android:layout_marginTop="4pt"
 | 
			
		||||
                        android:layout_marginEnd="8pt"
 | 
			
		||||
                        android:layout_marginRight="8pt"
 | 
			
		||||
                        android:layout_marginBottom="4pt"
 | 
			
		||||
                        android:alpha="0.7"
 | 
			
		||||
                        android:paddingRight="8pt"
 | 
			
		||||
                        android:text="Yggdrasil will use these DNS servers in VPN config when service starts. All your DNS requests will be resolved through them."
 | 
			
		||||
                        android:textAllCaps="false"
 | 
			
		||||
                        android:textAppearance="@style/TextAppearance.AppCompat.Small"
 | 
			
		||||
                        android:textSize="12sp" />
 | 
			
		||||
 | 
			
		||||
                </LinearLayout>
 | 
			
		||||
            </ScrollView>
 | 
			
		||||
 | 
			
		||||
        </LinearLayout>
 | 
			
		||||
    </FrameLayout>
 | 
			
		||||
</LinearLayout>
 | 
			
		||||
| 
						 | 
				
			
			@ -94,7 +94,7 @@
 | 
			
		|||
                                android:layout_weight="2" />
 | 
			
		||||
 | 
			
		||||
                            <Switch
 | 
			
		||||
                                android:id="@+id/enableMulticastBeacon"
 | 
			
		||||
                                android:id="@+id/enableYggdrasil"
 | 
			
		||||
                                android:layout_width="wrap_content"
 | 
			
		||||
                                android:layout_height="wrap_content" />
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -347,6 +347,50 @@
 | 
			
		|||
                                app:srcCompat="@drawable/ic_baseline_chevron_right_24" />
 | 
			
		||||
                        </TableRow>
 | 
			
		||||
 | 
			
		||||
                        <TableRow
 | 
			
		||||
                            android:id="@+id/dnsTableRow"
 | 
			
		||||
                            android:layout_width="match_parent"
 | 
			
		||||
                            android:layout_height="match_parent"
 | 
			
		||||
                            android:background="?android:attr/selectableItemBackground"
 | 
			
		||||
                            android:clickable="true"
 | 
			
		||||
                            android:paddingStart="4pt"
 | 
			
		||||
                            android:paddingTop="6pt"
 | 
			
		||||
                            android:paddingEnd="4pt"
 | 
			
		||||
                            android:paddingBottom="6pt">
 | 
			
		||||
 | 
			
		||||
                            <TextView
 | 
			
		||||
                                android:id="@+id/dnsLabel"
 | 
			
		||||
                                android:layout_width="wrap_content"
 | 
			
		||||
                                android:layout_height="wrap_content"
 | 
			
		||||
                                android:text="DNS servers"
 | 
			
		||||
                                android:textColor="?attr/textDefault" />
 | 
			
		||||
 | 
			
		||||
                            <Space
 | 
			
		||||
                                android:layout_width="wrap_content"
 | 
			
		||||
                                android:layout_height="wrap_content"
 | 
			
		||||
                                android:layout_weight="2" />
 | 
			
		||||
 | 
			
		||||
                            <TextView
 | 
			
		||||
                                android:id="@+id/dnsValue"
 | 
			
		||||
                                android:layout_width="wrap_content"
 | 
			
		||||
                                android:layout_height="wrap_content"
 | 
			
		||||
                                android:alpha="0.5"
 | 
			
		||||
                                android:text="No servers"
 | 
			
		||||
                                android:textAlignment="textEnd" />
 | 
			
		||||
 | 
			
		||||
                            <ImageView
 | 
			
		||||
                                android:id="@+id/dnsChevron"
 | 
			
		||||
                                android:layout_width="wrap_content"
 | 
			
		||||
                                android:layout_height="match_parent"
 | 
			
		||||
                                android:layout_marginLeft="2pt"
 | 
			
		||||
                                android:alpha="0.4"
 | 
			
		||||
                                android:cropToPadding="false"
 | 
			
		||||
                                android:scaleType="fitEnd"
 | 
			
		||||
                                android:scaleX="1.2"
 | 
			
		||||
                                android:scaleY="1.2"
 | 
			
		||||
                                app:srcCompat="@drawable/ic_baseline_chevron_right_24" />
 | 
			
		||||
                        </TableRow>
 | 
			
		||||
 | 
			
		||||
                        <TableRow
 | 
			
		||||
                            android:id="@+id/settingsTableRow"
 | 
			
		||||
                            android:layout_width="match_parent"
 | 
			
		||||
| 
						 | 
				
			
			@ -426,12 +470,12 @@
 | 
			
		|||
                        android:layout_height="wrap_content"
 | 
			
		||||
                        android:layout_marginStart="16pt"
 | 
			
		||||
                        android:layout_marginLeft="16pt"
 | 
			
		||||
                        android:layout_marginTop="2pt"
 | 
			
		||||
                        android:layout_marginTop="4pt"
 | 
			
		||||
                        android:layout_marginEnd="8pt"
 | 
			
		||||
                        android:layout_marginRight="8pt"
 | 
			
		||||
                        android:alpha="0.7"
 | 
			
		||||
                        android:paddingRight="8pt"
 | 
			
		||||
                        android:text="You must re-enable Yggdrasil after modifying Peers or Settings to make any changes effective."
 | 
			
		||||
                        android:text="You must re-enable Yggdrasil after modifying Peers, DNS servers or Settings to make any changes effective."
 | 
			
		||||
                        android:textAllCaps="false"
 | 
			
		||||
                        android:textAppearance="@style/TextAppearance.AppCompat.Small"
 | 
			
		||||
                        android:textSize="12sp" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -128,7 +128,7 @@
 | 
			
		|||
                        android:layout_height="wrap_content"
 | 
			
		||||
                        android:layout_marginStart="16pt"
 | 
			
		||||
                        android:layout_marginLeft="16pt"
 | 
			
		||||
                        android:layout_marginTop="2pt"
 | 
			
		||||
                        android:layout_marginTop="4pt"
 | 
			
		||||
                        android:layout_marginEnd="8pt"
 | 
			
		||||
                        android:layout_marginRight="8pt"
 | 
			
		||||
                        android:layout_marginBottom="4pt"
 | 
			
		||||
| 
						 | 
				
			
			@ -237,7 +237,7 @@
 | 
			
		|||
                        android:layout_height="wrap_content"
 | 
			
		||||
                        android:layout_marginStart="16pt"
 | 
			
		||||
                        android:layout_marginLeft="16pt"
 | 
			
		||||
                        android:layout_marginTop="2pt"
 | 
			
		||||
                        android:layout_marginTop="4pt"
 | 
			
		||||
                        android:layout_marginEnd="8pt"
 | 
			
		||||
                        android:layout_marginRight="8pt"
 | 
			
		||||
                        android:alpha="0.7"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										34
									
								
								app/src/main/res/layout/dialog_add_dns_server.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								app/src/main/res/layout/dialog_add_dns_server.xml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,34 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent">
 | 
			
		||||
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:orientation="vertical"
 | 
			
		||||
        android:paddingLeft="10pt"
 | 
			
		||||
        android:paddingTop="4pt"
 | 
			
		||||
        android:paddingRight="10pt"
 | 
			
		||||
        android:paddingBottom="4pt">
 | 
			
		||||
 | 
			
		||||
        <TextView
 | 
			
		||||
            android:id="@+id/textView2"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:text="Enter the IP address of DNS server to add. It will be used by OS and all apps when Yggdrasil starts." />
 | 
			
		||||
 | 
			
		||||
        <com.google.android.material.textfield.TextInputLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content">
 | 
			
		||||
 | 
			
		||||
            <com.google.android.material.textfield.TextInputEditText
 | 
			
		||||
                android:id="@+id/addDnsInput"
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_marginTop="4pt"
 | 
			
		||||
                android:lines="1"
 | 
			
		||||
                android:hint="8.8.8.8 or 302:7991::53" />
 | 
			
		||||
        </com.google.android.material.textfield.TextInputLayout>
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
</FrameLayout>
 | 
			
		||||
| 
						 | 
				
			
			@ -27,6 +27,7 @@
 | 
			
		|||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_marginTop="4pt"
 | 
			
		||||
                android:lines="1"
 | 
			
		||||
                android:hint="tcp://address:port" />
 | 
			
		||||
        </com.google.android.material.textfield.TextInputLayout>
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,6 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:id="@+id/tableRow"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="wrap_content">
 | 
			
		||||
| 
						 | 
				
			
			@ -16,7 +15,7 @@
 | 
			
		|||
        android:layout_marginBottom="12dp"
 | 
			
		||||
        android:ellipsize="end"
 | 
			
		||||
        android:singleLine="true"
 | 
			
		||||
        android:text="TextView"
 | 
			
		||||
        android:text=""
 | 
			
		||||
        android:textColor="?attr/textDefault"
 | 
			
		||||
        app:layout_constraintBottom_toBottomOf="parent"
 | 
			
		||||
        app:layout_constraintEnd_toStartOf="@+id/deletePeerButton"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue