diff options
Diffstat (limited to 'app/src/main/java/org/pacien/tincapp/activities/StatusActivity.kt')
-rw-r--r-- | app/src/main/java/org/pacien/tincapp/activities/StatusActivity.kt | 105 |
1 files changed, 73 insertions, 32 deletions
diff --git a/app/src/main/java/org/pacien/tincapp/activities/StatusActivity.kt b/app/src/main/java/org/pacien/tincapp/activities/StatusActivity.kt index ca572ea..b4ba7dd 100644 --- a/app/src/main/java/org/pacien/tincapp/activities/StatusActivity.kt +++ b/app/src/main/java/org/pacien/tincapp/activities/StatusActivity.kt | |||
@@ -2,6 +2,7 @@ package org.pacien.tincapp.activities | |||
2 | 2 | ||
3 | import android.content.Intent | 3 | import android.content.Intent |
4 | import android.os.Bundle | 4 | import android.os.Bundle |
5 | import android.support.v4.widget.SwipeRefreshLayout | ||
5 | import android.support.v7.app.AlertDialog | 6 | import android.support.v7.app.AlertDialog |
6 | import android.view.Menu | 7 | import android.view.Menu |
7 | import android.view.MenuItem | 8 | import android.view.MenuItem |
@@ -17,16 +18,33 @@ import org.pacien.tincapp.R | |||
17 | import org.pacien.tincapp.commands.Tinc | 18 | import org.pacien.tincapp.commands.Tinc |
18 | import org.pacien.tincapp.service.TincVpnService | 19 | import org.pacien.tincapp.service.TincVpnService |
19 | import org.pacien.tincapp.service.VpnInterfaceConfiguration | 20 | import org.pacien.tincapp.service.VpnInterfaceConfiguration |
21 | import org.pacien.tincapp.utils.setElements | ||
22 | import org.pacien.tincapp.utils.setText | ||
23 | import java.util.* | ||
24 | import kotlin.concurrent.timerTask | ||
20 | 25 | ||
21 | /** | 26 | /** |
22 | * @author pacien | 27 | * @author pacien |
23 | */ | 28 | */ |
24 | class StatusActivity : BaseActivity(), AdapterView.OnItemClickListener { | 29 | class StatusActivity : BaseActivity(), AdapterView.OnItemClickListener, SwipeRefreshLayout.OnRefreshListener { |
30 | |||
31 | private var nodeListAdapter: ArrayAdapter<String>? = null | ||
32 | private var refreshTimer: Timer? = null | ||
33 | private var updateView: Boolean = false | ||
25 | 34 | ||
26 | override fun onCreate(savedInstanceState: Bundle?) { | 35 | override fun onCreate(savedInstanceState: Bundle?) { |
27 | super.onCreate(savedInstanceState) | 36 | super.onCreate(savedInstanceState) |
37 | |||
38 | nodeListAdapter = ArrayAdapter<String>(this, R.layout.fragment_list_item) | ||
39 | refreshTimer = Timer(true) | ||
40 | |||
28 | layoutInflater.inflate(R.layout.page_status, main_content) | 41 | layoutInflater.inflate(R.layout.page_status, main_content) |
29 | writeContent() | 42 | node_list_wrapper.setOnRefreshListener(this) |
43 | node_list.addHeaderView(layoutInflater.inflate(R.layout.fragment_network_status_header, node_list, false), null, false) | ||
44 | node_list.addFooterView(View(this), null, false) | ||
45 | node_list.emptyView = node_list_empty | ||
46 | node_list.onItemClickListener = this | ||
47 | node_list.adapter = nodeListAdapter | ||
30 | } | 48 | } |
31 | 49 | ||
32 | override fun onCreateOptionsMenu(m: Menu): Boolean { | 50 | override fun onCreateOptionsMenu(m: Menu): Boolean { |
@@ -34,55 +52,78 @@ class StatusActivity : BaseActivity(), AdapterView.OnItemClickListener { | |||
34 | return super.onCreateOptionsMenu(m) | 52 | return super.onCreateOptionsMenu(m) |
35 | } | 53 | } |
36 | 54 | ||
37 | override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { | 55 | override fun onDestroy() { |
38 | val nodeName = (view as TextView).text.toString() | 56 | super.onDestroy() |
39 | val v = layoutInflater.inflate(R.layout.dialog_text_monopsace, main_content, false) | 57 | refreshTimer?.cancel() |
40 | v.dialog_text_monospace.text = Tinc.info(TincVpnService.getCurrentNetName()!!, nodeName) | 58 | nodeListAdapter = null |
41 | 59 | refreshTimer = null | |
42 | AlertDialog.Builder(this) | ||
43 | .setTitle(R.string.title_node_info) | ||
44 | .setView(v) | ||
45 | .setPositiveButton(R.string.action_close) { _, _ -> /* nop */ } | ||
46 | .show() | ||
47 | } | 60 | } |
48 | 61 | ||
49 | fun stopVpn(@Suppress("UNUSED_PARAMETER") i: MenuItem) { | 62 | override fun onStart() { |
50 | TincVpnService.stopVpn() | 63 | super.onStart() |
51 | startActivity(Intent(this, StartActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)) | 64 | writeNetworkInfo(TincVpnService.getCurrentInterfaceCfg() ?: VpnInterfaceConfiguration()) |
52 | finish() | 65 | updateView = true |
66 | onRefresh() | ||
67 | updateNodeList() | ||
53 | } | 68 | } |
54 | 69 | ||
55 | private fun TextView.setText(list: List<String>) { | 70 | override fun onStop() { |
56 | if (list.isNotEmpty()) text = list.joinToString("\n") | 71 | super.onStop() |
57 | else text = getString(R.string.value_none) | 72 | updateView = false |
58 | } | 73 | } |
59 | 74 | ||
60 | private fun getNodeNames() = Tinc.dumpNodes(TincVpnService.getCurrentNetName()!!).map { it.substringBefore(" ") } | 75 | override fun onRefresh() { |
76 | val nodes = getNodeNames() | ||
77 | runOnUiThread { | ||
78 | nodeListAdapter?.setElements(nodes) | ||
79 | node_list_wrapper.isRefreshing = false | ||
80 | } | ||
81 | } | ||
61 | 82 | ||
62 | private fun writeContent() { | 83 | override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { |
63 | node_list.addHeaderView(layoutInflater.inflate(R.layout.fragment_network_status_header, node_list, false), null, false) | 84 | val nodeName = (view as TextView).text.toString() |
64 | node_list.addFooterView(View(this), null, false) | 85 | val dialogTextView = layoutInflater.inflate(R.layout.dialog_text_monopsace, main_content, false) |
65 | node_list.emptyView = node_list_empty | 86 | dialogTextView.dialog_text_monospace.text = Tinc.info(TincVpnService.getCurrentNetName()!!, nodeName) |
66 | node_list.onItemClickListener = this | ||
67 | node_list.adapter = ArrayAdapter<String>(this, R.layout.fragment_list_item, getNodeNames()) | ||
68 | 87 | ||
69 | text_network_name.text = TincVpnService.getCurrentNetName() ?: getString(R.string.value_none) | 88 | AlertDialog.Builder(this) |
70 | writeNetworkInfo(TincVpnService.getCurrentInterfaceCfg() ?: VpnInterfaceConfiguration()) | 89 | .setTitle(R.string.title_node_info) |
90 | .setView(dialogTextView) | ||
91 | .setPositiveButton(R.string.action_close) { _, _ -> /* nop */ } | ||
92 | .show() | ||
71 | } | 93 | } |
72 | 94 | ||
73 | 95 | fun writeNetworkInfo(cfg: VpnInterfaceConfiguration) { | |
74 | private fun writeNetworkInfo(cfg: VpnInterfaceConfiguration) { | 96 | text_network_name.text = TincVpnService.getCurrentNetName() ?: getString(R.string.value_none) |
75 | text_network_ip_addresses.setText(cfg.addresses.map { it.toString() }) | 97 | text_network_ip_addresses.setText(cfg.addresses.map { it.toString() }) |
76 | text_network_routes.setText(cfg.routes.map { it.toString() }) | 98 | text_network_routes.setText(cfg.routes.map { it.toString() }) |
77 | text_network_dns_servers.setText(cfg.dnsServers) | 99 | text_network_dns_servers.setText(cfg.dnsServers) |
78 | text_network_search_domains.setText(cfg.searchDomains) | 100 | 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) | 101 | 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 | 102 | block_network_allowed_applications.visibility = if (cfg.allowedApplications.isNotEmpty()) View.VISIBLE else View.GONE |
82 | text_network_allowed_applications.setText(cfg.allowedApplications) | 103 | text_network_allowed_applications.setText(cfg.allowedApplications) |
83 | |||
84 | block_network_disallowed_applications.visibility = if (cfg.disallowedApplications.isNotEmpty()) View.VISIBLE else View.GONE | 104 | block_network_disallowed_applications.visibility = if (cfg.disallowedApplications.isNotEmpty()) View.VISIBLE else View.GONE |
85 | text_network_disallowed_applications.setText(cfg.disallowedApplications) | 105 | text_network_disallowed_applications.setText(cfg.disallowedApplications) |
86 | } | 106 | } |
87 | 107 | ||
108 | fun updateNodeList() { | ||
109 | refreshTimer?.schedule(timerTask { | ||
110 | onRefresh() | ||
111 | if (updateView) updateNodeList() | ||
112 | }, REFRESH_RATE) | ||
113 | } | ||
114 | |||
115 | fun stopVpn(@Suppress("UNUSED_PARAMETER") i: MenuItem) { | ||
116 | TincVpnService.stopVpn() | ||
117 | startActivity(Intent(this, StartActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)) | ||
118 | finish() | ||
119 | } | ||
120 | |||
121 | companion object { | ||
122 | private val REFRESH_RATE = 5000L | ||
123 | |||
124 | fun getNodeNames() = | ||
125 | if (TincVpnService.isConnected()) Tinc.dumpNodes(TincVpnService.getCurrentNetName()!!).map { it.substringBefore(" ") } | ||
126 | else emptyList() | ||
127 | } | ||
128 | |||
88 | } | 129 | } |