aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPacien TRAN-GIRARD2017-07-04 18:51:57 +0200
committerPacien TRAN-GIRARD2017-07-04 18:51:57 +0200
commit80394001852e8400fd2c3d30e441306957d32243 (patch)
tree6835941520e9fc0e63324bb42eb08a4b6d50f746
parent0b3eef56d244bf40598cba66b1e48479ecbdfaef (diff)
downloadtincapp-80394001852e8400fd2c3d30e441306957d32243.tar.gz
Add status activity
-rw-r--r--app/src/main/AndroidManifest.xml5
-rw-r--r--app/src/main/java/org/pacien/tincapp/activities/StartActivity.kt8
-rw-r--r--app/src/main/java/org/pacien/tincapp/activities/StatusActivity.kt88
-rw-r--r--app/src/main/java/org/pacien/tincapp/commands/Executor.kt11
-rw-r--r--app/src/main/java/org/pacien/tincapp/commands/Tinc.kt2
-rw-r--r--app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt44
-rw-r--r--app/src/main/java/org/pacien/tincapp/service/VpnInterfaceConfiguraton.kt28
-rw-r--r--app/src/main/res/drawable/ic_build_primary_24dp.xml (renamed from app/src/main/res/drawable/ic_build_black_24dp.xml)0
-rw-r--r--app/src/main/res/drawable/ic_stop_primary_24dp.xml9
-rw-r--r--app/src/main/res/layout/dialog_frame.xml1
-rw-r--r--app/src/main/res/layout/dialog_text_monopsace.xml15
-rw-r--r--app/src/main/res/layout/fragment_network_status_header.xml122
-rw-r--r--app/src/main/res/layout/page_status.xml22
-rw-r--r--app/src/main/res/menu/menu_start.xml2
-rw-r--r--app/src/main/res/menu/menu_status.xml14
-rw-r--r--app/src/main/res/values/strings.xml17
16 files changed, 356 insertions, 32 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6558873..89e618c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -32,6 +32,11 @@
32 </activity> 32 </activity>
33 33
34 <activity 34 <activity
35 android:name=".activities.StatusActivity"
36 android:theme="@style/AppTheme.NoActionBar">
37 </activity>
38
39 <activity
35 android:name=".activities.PromptActivity" 40 android:name=".activities.PromptActivity"
36 android:theme="@android:style/Theme.Translucent.NoTitleBar"> 41 android:theme="@android:style/Theme.Translucent.NoTitleBar">
37 </activity> 42 </activity>
diff --git a/app/src/main/java/org/pacien/tincapp/activities/StartActivity.kt b/app/src/main/java/org/pacien/tincapp/activities/StartActivity.kt
index c438be0..19d01e6 100644
--- a/app/src/main/java/org/pacien/tincapp/activities/StartActivity.kt
+++ b/app/src/main/java/org/pacien/tincapp/activities/StartActivity.kt
@@ -12,6 +12,7 @@ import kotlinx.android.synthetic.main.base.*
12import kotlinx.android.synthetic.main.page_start.* 12import kotlinx.android.synthetic.main.page_start.*
13import org.pacien.tincapp.R 13import org.pacien.tincapp.R
14import org.pacien.tincapp.context.AppPaths 14import org.pacien.tincapp.context.AppPaths
15import org.pacien.tincapp.service.TincVpnService
15 16
16/** 17/**
17 * @author pacien 18 * @author pacien
@@ -29,6 +30,13 @@ class StartActivity : BaseActivity(), AdapterView.OnItemClickListener {
29 return super.onCreateOptionsMenu(m) 30 return super.onCreateOptionsMenu(m)
30 } 31 }
31 32
33 override fun onResume() {
34 super.onResume()
35
36 if (TincVpnService.isConnected()) startActivity(Intent(this, StatusActivity::class.java)
37 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK))
38 }
39
32 override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { 40 override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
33 PromptActivity.requestVpnPermission((view as TextView).text.toString()) 41 PromptActivity.requestVpnPermission((view as TextView).text.toString())
34 } 42 }
diff --git a/app/src/main/java/org/pacien/tincapp/activities/StatusActivity.kt b/app/src/main/java/org/pacien/tincapp/activities/StatusActivity.kt
new file mode 100644
index 0000000..ca572ea
--- /dev/null
+++ b/app/src/main/java/org/pacien/tincapp/activities/StatusActivity.kt
@@ -0,0 +1,88 @@
1package org.pacien.tincapp.activities
2
3import android.content.Intent
4import android.os.Bundle
5import android.support.v7.app.AlertDialog
6import android.view.Menu
7import android.view.MenuItem
8import android.view.View
9import android.widget.AdapterView
10import android.widget.ArrayAdapter
11import android.widget.TextView
12import kotlinx.android.synthetic.main.base.*
13import kotlinx.android.synthetic.main.dialog_text_monopsace.view.*
14import kotlinx.android.synthetic.main.fragment_network_status_header.*
15import kotlinx.android.synthetic.main.page_status.*
16import org.pacien.tincapp.R
17import org.pacien.tincapp.commands.Tinc
18import org.pacien.tincapp.service.TincVpnService
19import org.pacien.tincapp.service.VpnInterfaceConfiguration
20
21/**
22 * @author pacien
23 */
24class StatusActivity : BaseActivity(), AdapterView.OnItemClickListener {
25
26 override fun onCreate(savedInstanceState: Bundle?) {
27 super.onCreate(savedInstanceState)
28 layoutInflater.inflate(R.layout.page_status, main_content)
29 writeContent()
30 }
31
32 override fun onCreateOptionsMenu(m: Menu): Boolean {
33 menuInflater.inflate(R.menu.menu_status, m)
34 return super.onCreateOptionsMenu(m)
35 }
36
37 override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
38 val nodeName = (view as TextView).text.toString()
39 val v = layoutInflater.inflate(R.layout.dialog_text_monopsace, main_content, false)
40 v.dialog_text_monospace.text = Tinc.info(TincVpnService.getCurrentNetName()!!, nodeName)
41
42 AlertDialog.Builder(this)
43 .setTitle(R.string.title_node_info)
44 .setView(v)
45 .setPositiveButton(R.string.action_close) { _, _ -> /* nop */ }
46 .show()
47 }
48
49 fun stopVpn(@Suppress("UNUSED_PARAMETER") i: MenuItem) {
50 TincVpnService.stopVpn()
51 startActivity(Intent(this, StartActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
52 finish()
53 }
54
55 private fun TextView.setText(list: List<String>) {
56 if (list.isNotEmpty()) text = list.joinToString("\n")
57 else text = getString(R.string.value_none)
58 }
59
60 private fun getNodeNames() = Tinc.dumpNodes(TincVpnService.getCurrentNetName()!!).map { it.substringBefore(" ") }
61
62 private fun writeContent() {
63 node_list.addHeaderView(layoutInflater.inflate(R.layout.fragment_network_status_header, node_list, false), null, false)
64 node_list.addFooterView(View(this), null, false)
65 node_list.emptyView = node_list_empty
66 node_list.onItemClickListener = this
67 node_list.adapter = ArrayAdapter<String>(this, R.layout.fragment_list_item, getNodeNames())
68
69 text_network_name.text = TincVpnService.getCurrentNetName() ?: getString(R.string.value_none)
70 writeNetworkInfo(TincVpnService.getCurrentInterfaceCfg() ?: VpnInterfaceConfiguration())
71 }
72
73
74 private fun writeNetworkInfo(cfg: VpnInterfaceConfiguration) {
75 text_network_ip_addresses.setText(cfg.addresses.map { it.toString() })
76 text_network_routes.setText(cfg.routes.map { it.toString() })
77 text_network_dns_servers.setText(cfg.dnsServers)
78 text_network_search_domains.setText(cfg.searchDomains)
79 text_network_allow_bypass.text = getString(if (cfg.allowBypass) R.string.value_yes else R.string.value_no)
80
81 block_network_allowed_applications.visibility = if (cfg.allowedApplications.isNotEmpty()) View.VISIBLE else View.GONE
82 text_network_allowed_applications.setText(cfg.allowedApplications)
83
84 block_network_disallowed_applications.visibility = if (cfg.disallowedApplications.isNotEmpty()) View.VISIBLE else View.GONE
85 text_network_disallowed_applications.setText(cfg.disallowedApplications)
86 }
87
88}
diff --git a/app/src/main/java/org/pacien/tincapp/commands/Executor.kt b/app/src/main/java/org/pacien/tincapp/commands/Executor.kt
index 160f0cd..c93de64 100644
--- a/app/src/main/java/org/pacien/tincapp/commands/Executor.kt
+++ b/app/src/main/java/org/pacien/tincapp/commands/Executor.kt
@@ -3,7 +3,6 @@ package org.pacien.tincapp.commands
3import java.io.BufferedReader 3import java.io.BufferedReader
4import java.io.IOException 4import java.io.IOException
5import java.io.InputStreamReader 5import java.io.InputStreamReader
6import java.util.*
7 6
8/** 7/**
9 * @author pacien 8 * @author pacien
@@ -29,15 +28,7 @@ internal object Executor {
29 fun call(cmd: Command): List<String> { 28 fun call(cmd: Command): List<String> {
30 val proc = ProcessBuilder(cmd.asList()).start() 29 val proc = ProcessBuilder(cmd.asList()).start()
31 val outputReader = BufferedReader(InputStreamReader(proc.inputStream)) 30 val outputReader = BufferedReader(InputStreamReader(proc.inputStream))
32 31 return outputReader.readLines()
33 var line: String? = outputReader.readLine()
34 val list = LinkedList<String>()
35 while (line != null) {
36 line = outputReader.readLine()
37 list.add(line)
38 }
39
40 return list
41 } 32 }
42 33
43} 34}
diff --git a/app/src/main/java/org/pacien/tincapp/commands/Tinc.kt b/app/src/main/java/org/pacien/tincapp/commands/Tinc.kt
index 22cbe71..e8ebb21 100644
--- a/app/src/main/java/org/pacien/tincapp/commands/Tinc.kt
+++ b/app/src/main/java/org/pacien/tincapp/commands/Tinc.kt
@@ -30,7 +30,7 @@ object Tinc {
30 } 30 }
31 31
32 @Throws(IOException::class) 32 @Throws(IOException::class)
33 fun dumpNodes(netName: String, reachable: Boolean): List<String> = 33 fun dumpNodes(netName: String, reachable: Boolean = false): List<String> =
34 Executor.call( 34 Executor.call(
35 if (reachable) newCommand(netName).withArguments("dump", "reachable", "nodes") 35 if (reachable) newCommand(netName).withArguments("dump", "reachable", "nodes")
36 else newCommand(netName).withArguments("dump", "nodes")) 36 else newCommand(netName).withArguments("dump", "nodes"))
diff --git a/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt b/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt