diff --git a/app/build.gradle b/app/build.gradle index cf1cf5a..aa8a25e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "io.github.chronosx88.yggdrasil" minSdkVersion 21 targetSdkVersion 29 - versionCode 2 - versionName "1.1" + versionCode 3 + versionName "1.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" project.ext.set("archivesBaseName", project.getParent().name+"-"+versionName) } @@ -38,17 +38,6 @@ android { } } -task ndkBuild(type: Exec) { - def rootDir = project.rootDir - workingDir = new File(rootDir,"yggdrasil") - commandLine 'make' -} - -gradle.projectsEvaluated { - tasks.compileDebugKotlin.dependsOn(ndkBuild) -} - - dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation project(path: ':yggdrasil') diff --git a/app/src/main/java/io/github/chronosx88/yggdrasil/DNSListActivity.kt b/app/src/main/java/io/github/chronosx88/yggdrasil/DNSListActivity.kt index 935ee72..bf0e227 100644 --- a/app/src/main/java/io/github/chronosx88/yggdrasil/DNSListActivity.kt +++ b/app/src/main/java/io/github/chronosx88/yggdrasil/DNSListActivity.kt @@ -92,7 +92,7 @@ class DNSListActivity : AppCompatActivity() { val result = Intent(this, MainActivity::class.java) var adapter = findViewById(R.id.dnsList).adapter as SelectDNSInfoListAdapter val selectedDNS = adapter.getSelectedDNS() - if(selectedDNS.size>0) { + if(selectedDNS.isNotEmpty()) { result.putExtra(MainActivity.DNS_LIST, MainActivity.serializeDNSInfoSet2StringList(selectedDNS)) setResult(Activity.RESULT_OK, result) finish() diff --git a/app/src/main/java/io/github/chronosx88/yggdrasil/MainActivity.kt b/app/src/main/java/io/github/chronosx88/yggdrasil/MainActivity.kt index 3d0ff18..d15c230 100644 --- a/app/src/main/java/io/github/chronosx88/yggdrasil/MainActivity.kt +++ b/app/src/main/java/io/github/chronosx88/yggdrasil/MainActivity.kt @@ -163,8 +163,6 @@ class MainActivity : AppCompatActivity() { private fun startVpn(){ Log.d(TAG,"Start") - val ipLayout = findViewById(R.id.ipLayout) - ipLayout.visibility = View.VISIBLE val intent= VpnService.prepare(this) if (intent!=null){ startActivityForResult(intent, VPN_REQUEST_CODE) @@ -253,13 +251,16 @@ class MainActivity : AppCompatActivity() { when (resultCode) { STATUS_START -> print("service started") STATUS_FINISH -> { + isStarted = true + val ipLayout = findViewById(R.id.ipLayout) + ipLayout.visibility = View.VISIBLE val result: String = data!!.getStringExtra(IPv6) findViewById(R.id.ip).text = result - isStarted = true } STATUS_STOP -> { isStarted = false - finish() + val ipLayout = findViewById(R.id.ipLayout) + ipLayout.visibility = View.GONE } else -> { // Note the block diff --git a/app/src/main/java/io/github/chronosx88/yggdrasil/YggdrasilTunService.kt b/app/src/main/java/io/github/chronosx88/yggdrasil/YggdrasilTunService.kt index 5c9ed99..f0a2ce9 100644 --- a/app/src/main/java/io/github/chronosx88/yggdrasil/YggdrasilTunService.kt +++ b/app/src/main/java/io/github/chronosx88/yggdrasil/YggdrasilTunService.kt @@ -5,13 +5,12 @@ import android.content.Intent import android.net.VpnService import android.os.ParcelFileDescriptor import android.system.OsConstants +import android.util.Log import com.google.gson.Gson import dummy.ConduitEndpoint import io.github.chronosx88.yggdrasil.models.DNSInfo import io.github.chronosx88.yggdrasil.models.PeerInfo -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.cancel -import kotlinx.coroutines.launch +import kotlinx.coroutines.* import mobile.Mobile import mobile.Yggdrasil import java.io.* @@ -40,11 +39,9 @@ class YggdrasilTunService : VpnService() { } } private var tunInterface: ParcelFileDescriptor? = null - private lateinit var yggConduitEndpoint: ConduitEndpoint private var tunInputStream: InputStream? = null private var tunOutputStream: OutputStream? = null - private lateinit var readCoroutine: CoroutineContext - private lateinit var writeCoroutine: CoroutineContext + private var scope: CoroutineScope? = null override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { @@ -75,37 +72,40 @@ class YggdrasilTunService : VpnService() { config = fixConfig(config, peers) configJson = gson.toJson(config).toByteArray() - yggConduitEndpoint = ygg.startJSON(configJson) + var yggConduitEndpoint = ygg.startJSON(configJson) val address = ygg.addressString // hack for getting generic ipv6 string from NodeID var builder = Builder() .addAddress(address, 7) .allowFamily(OsConstants.AF_INET) .setMtu(MAX_PACKET_SIZE) - if(dns.size>0){ - for (d in dns){ + if (dns.size > 0) { + for (d in dns) { builder.addDnsServer(d.address) } } tunInterface = builder.establish() tunInputStream = FileInputStream(tunInterface!!.fileDescriptor) tunOutputStream = FileOutputStream(tunInterface!!.fileDescriptor) - readCoroutine = GlobalScope.launch { + val job = SupervisorJob() + scope = CoroutineScope(Dispatchers.Default + job) + scope!!.launch { val buffer = ByteArray(2048) - try{ - while (true) { - readPacketsFromTun(buffer) + try { + while (!isClosed) { + readPacketsFromTun(yggConduitEndpoint, buffer) } - } catch (e: IOException){ + } catch (e: IOException) { e.printStackTrace() tunInputStream!!.close() } } - writeCoroutine = GlobalScope.launch { - while (true) { - writePacketsToTun() + scope!!.launch { + while (!isClosed) { + writePacketsToTun(yggConduitEndpoint) } } + val intent: Intent = Intent().putExtra(MainActivity.IPv6, address) pi.send(this, MainActivity.STATUS_FINISH, intent) } @@ -141,21 +141,19 @@ class YggdrasilTunService : VpnService() { return config } - private fun readPacketsFromTun(buffer: ByteArray) { - if(!isClosed) { - // Read the outgoing packet from the input stream. - val length = tunInputStream!!.read(buffer) - if (length > 0) { - val byteBuffer = ByteBuffer.allocate(length) - byteBuffer.put(buffer, 0, length) - yggConduitEndpoint.send(byteBuffer.array()) - } else { - Thread.sleep(10) - } + private fun readPacketsFromTun(yggConduitEndpoint: ConduitEndpoint, buffer: ByteArray) { + // Read the outgoing packet from the input stream. + val length = tunInputStream!!.read(buffer) + if (length > 0) { + val byteBuffer = ByteBuffer.allocate(length) + byteBuffer.put(buffer, 0, length) + yggConduitEndpoint.send(byteBuffer.array()) + } else { + Thread.sleep(10) } } - private fun writePacketsToTun() { + private fun writePacketsToTun(yggConduitEndpoint: ConduitEndpoint) { if(tunOutputStream != null) { val buffer = yggConduitEndpoint.recv() if(buffer!=null) { @@ -170,12 +168,12 @@ class YggdrasilTunService : VpnService() { private fun stopVpn(pi: PendingIntent) { isClosed = true; - readCoroutine.cancel() - writeCoroutine.cancel() + scope!!.coroutineContext.cancelChildren() tunInputStream!!.close() tunOutputStream!!.close() tunInterface!!.close() tunInterface = null + Log.d(TAG,"Stop is running from service") ygg.stop() val intent: Intent = Intent() pi.send(this, MainActivity.STATUS_STOP, intent) diff --git a/app/src/main/java/io/github/chronosx88/yggdrasil/models/config/SelectDNSInfoAdapter.kt b/app/src/main/java/io/github/chronosx88/yggdrasil/models/config/SelectDNSInfoAdapter.kt index bb49578..330c878 100644 --- a/app/src/main/java/io/github/chronosx88/yggdrasil/models/config/SelectDNSInfoAdapter.kt +++ b/app/src/main/java/io/github/chronosx88/yggdrasil/models/config/SelectDNSInfoAdapter.kt @@ -23,7 +23,7 @@ class SelectDNSInfoListAdapter( private var currentDNS: MutableSet = currentDNS override fun getItem(position: Int): DNSInfo? { - return allDNS.get(position) + return allDNS[position] } override fun getCount(): Int { @@ -78,13 +78,6 @@ class SelectDNSInfoListAdapter( allDNS.add(peerInfo) } - fun addAll(index: Int, peerInfo: ArrayList){ - currentDNS.addAll(peerInfo) - allDNS.removeAll(peerInfo) - allDNS.addAll(index, peerInfo) - this.notifyDataSetChanged() - } - fun sort(){ allDNS = ArrayList(allDNS.sortedWith(compareBy { it.ping })) this.notifyDataSetChanged() diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 26b0895..910d64c 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -14,10 +14,11 @@ android:layout_margin="20dp" android:background="@drawable/info_panel_rounded_corner" android:gravity="left" + android:paddingLeft="20dp" android:orientation="vertical" app:layout_constraintTop_toTopOf="parent" - android:visibility="gone" - android:animateLayoutChanges="true"> + android:animateLayoutChanges="true" + android:visibility="gone"> - + android:layout_height="wrap_content" + app:layout_constraintTop_toTopOf="parent"> + +