diff options
Diffstat (limited to 'app')
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.* | |||
12 | import kotlinx.android.synthetic.main.page_start.* | 12 | import kotlinx.android.synthetic.main.page_start.* |
13 | import org.pacien.tincapp.R | 13 | import org.pacien.tincapp.R |
14 | import org.pacien.tincapp.context.AppPaths | 14 | import org.pacien.tincapp.context.AppPaths |
15 | import 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 @@ | |||
1 | package org.pacien.tincapp.activities | ||
2 | |||
3 | import android.content.Intent | ||
4 | import android.os.Bundle | ||
5 | import android.support.v7.app.AlertDialog | ||
6 | import android.view.Menu | ||
7 | import android.view.MenuItem | ||
8 | import android.view.View | ||
9 | import android.widget.AdapterView | ||
10 | import android.widget.ArrayAdapter | ||
11 | import android.widget.TextView | ||
12 | import kotlinx.android.synthetic.main.base.* | ||
13 | import kotlinx.android.synthetic.main.dialog_text_monopsace.view.* | ||
14 | import kotlinx.android.synthetic.main.fragment_network_status_header.* | ||
15 | import kotlinx.android.synthetic.main.page_status.* | ||
16 | import org.pacien.tincapp.R | ||
17 | import org.pacien.tincapp.commands.Tinc | ||
18 | import org.pacien.tincapp.service.TincVpnService | ||
19 | import org.pacien.tincapp.service.VpnInterfaceConfiguration | ||
20 | |||
21 | /** | ||
22 | * @author pacien | ||
23 | */ | ||
24 | class 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 | |||
3 | import java.io.BufferedReader | 3 | import java.io.BufferedReader |
4 | import java.io.IOException | 4 | import java.io.IOException |
5 | import java.io.InputStreamReader | 5 | import java.io.InputStreamReader |
6 | import 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 index 30e2956..7813601 100644 --- a/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt +++ b/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt | |||
@@ -3,6 +3,7 @@ package org.pacien.tincapp.service | |||
3 | import android.app.Service | 3 | import android.app.Service |