aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/java/org/pacien/tincapp/activities/StatusActivity.kt
diff options
context:
space:
mode:
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.kt99
1 files changed, 63 insertions, 36 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 4b5384c..dc45947 100644
--- a/app/src/main/java/org/pacien/tincapp/activities/StatusActivity.kt
+++ b/app/src/main/java/org/pacien/tincapp/activities/StatusActivity.kt
@@ -1,6 +1,8 @@
1package org.pacien.tincapp.activities 1package org.pacien.tincapp.activities
2 2
3import android.app.ProgressDialog
3import android.content.Intent 4import android.content.Intent
5import android.content.IntentFilter
4import android.os.Bundle 6import android.os.Bundle
5import android.support.v4.widget.SwipeRefreshLayout 7import android.support.v4.widget.SwipeRefreshLayout
6import android.support.v7.app.AlertDialog 8import android.support.v7.app.AlertDialog
@@ -20,6 +22,8 @@ import org.pacien.tincapp.commands.Tinc
20import org.pacien.tincapp.data.VpnInterfaceConfiguration 22import org.pacien.tincapp.data.VpnInterfaceConfiguration
21import org.pacien.tincapp.extensions.Android.setElements 23import org.pacien.tincapp.extensions.Android.setElements
22import org.pacien.tincapp.extensions.Android.setText 24import org.pacien.tincapp.extensions.Android.setText
25import org.pacien.tincapp.intent.Actions
26import org.pacien.tincapp.intent.SimpleBroadcastReceiver
23import org.pacien.tincapp.service.TincVpnService 27import org.pacien.tincapp.service.TincVpnService
24import java.util.* 28import java.util.*
25import kotlin.concurrent.timerTask 29import kotlin.concurrent.timerTask
@@ -28,16 +32,15 @@ import kotlin.concurrent.timerTask
28 * @author pacien 32 * @author pacien
29 */ 33 */
30class StatusActivity : BaseActivity(), AdapterView.OnItemClickListener, SwipeRefreshLayout.OnRefreshListener { 34class StatusActivity : BaseActivity(), AdapterView.OnItemClickListener, SwipeRefreshLayout.OnRefreshListener {
31 35 private val shutdownBroadcastReceiver = SimpleBroadcastReceiver(IntentFilter(Actions.EVENT_DISCONNECTED), this::onVpnShutdown)
36 private var shutdownDialog: ProgressDialog? = null
32 private var nodeListAdapter: ArrayAdapter<String>? = null 37 private var nodeListAdapter: ArrayAdapter<String>? = null
33 private var refreshTimer: Timer? = null 38 private var refreshTimer: Timer? = null
34 private var updateView: Boolean = false 39 private var listNetworksAfterExit = true
35 40
36 override fun onCreate(savedInstanceState: Bundle?) { 41 override fun onCreate(savedInstanceState: Bundle?) {
37 super.onCreate(savedInstanceState) 42 super.onCreate(savedInstanceState)
38
39 nodeListAdapter = ArrayAdapter(this, R.layout.fragment_list_item) 43 nodeListAdapter = ArrayAdapter(this, R.layout.fragment_list_item)
40 refreshTimer = Timer(true)
41 44
42 layoutInflater.inflate(R.layout.fragment_list_view, main_content) 45 layoutInflater.inflate(R.layout.fragment_list_view, main_content)
43 list_wrapper.setOnRefreshListener(this) 46 list_wrapper.setOnRefreshListener(this)
@@ -45,6 +48,13 @@ class StatusActivity : BaseActivity(), AdapterView.OnItemClickListener, SwipeRef
45 list.addFooterView(View(this), null, false) 48 list.addFooterView(View(this), null, false)
46 list.onItemClickListener = this 49 list.onItemClickListener = this
47 list.adapter = nodeListAdapter 50 list.adapter = nodeListAdapter
51
52 if (intent.action == Actions.ACTION_DISCONNECT) {
53 listNetworksAfterExit = false
54 stopVpn()
55 } else {
56 listNetworksAfterExit = true
57 }
48 } 58 }
49 59
50 override fun onCreateOptionsMenu(m: Menu): Boolean { 60 override fun onCreateOptionsMenu(m: Menu): Boolean {
@@ -54,38 +64,35 @@ class StatusActivity : BaseActivity(), AdapterView.OnItemClickListener, SwipeRef
54 64
55 override fun onDestroy() { 65 override fun onDestroy() {
56 super.onDestroy() 66 super.onDestroy()
57 refreshTimer?.cancel()
58 nodeListAdapter = null 67 nodeListAdapter = null
59 refreshTimer = null 68 refreshTimer = null
60 } 69 }
61 70
62 override fun onStart() { 71 override fun onStart() {
63 super.onStart() 72 super.onStart()
73 refreshTimer = Timer(true)
74 refreshTimer?.schedule(timerTask { updateView() }, NOW, REFRESH_RATE)
64 writeNetworkInfo(TincVpnService.getCurrentInterfaceCfg() ?: VpnInterfaceConfiguration()) 75 writeNetworkInfo(TincVpnService.getCurrentInterfaceCfg() ?: VpnInterfaceConfiguration())
65 updateView = true
66 onRefresh()
67 updateNodeList()
68 } 76 }
69 77
70 override fun onStop() { 78 override fun onStop() {
79 refreshTimer?.cancel()
71 super.onStop() 80 super.onStop()
72 updateView = false
73 } 81 }
74 82
75 override fun onResume() { 83 override fun onResume() {
76 super.onResume() 84 super.onResume()
77 if (!TincVpnService.isConnected()) openStartActivity() 85 shutdownBroadcastReceiver.register()
86 updateView()
87 }
88
89 override fun onPause() {
90 shutdownBroadcastReceiver.unregister()
91 super.onPause()
78 } 92 }
79 93
80 override fun onRefresh() { 94 override fun onRefresh() {
81 getNodeNames().thenAccept { 95 refreshTimer?.schedule(timerTask { updateView() }, NOW)
82 runOnUiThread {
83 nodeListAdapter?.setElements(it)
84 node_list_placeholder.visibility = if (nodeListAdapter?.isEmpty != false) View.VISIBLE else View.GONE
85 list_wrapper.isRefreshing = false
86 if (!TincVpnService.isConnected()) openStartActivity()
87 }
88 }
89 } 96 }
90 97
91 override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { 98 override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
@@ -97,13 +104,26 @@ class StatusActivity : BaseActivity(), AdapterView.OnItemClickListener, SwipeRef
97 AlertDialog.Builder(this) 104 AlertDialog.Builder(this)
98 .setTitle(R.string.title_node_info) 105 .setTitle(R.string.title_node_info)
99 .setView(dialogTextView) 106 .setView(dialogTextView)
100 .setPositiveButton(R.string.action_close) { _, _ -> /* nop */ } 107 .setPositiveButton(R.string.action_close) { _, _ -> Unit }
101 .show() 108 .show()
102 } 109 }
103 } 110 }
104 } 111 }
105 112
106 fun writeNetworkInfo(cfg: VpnInterfaceConfiguration) { 113 private fun onVpnShutdown() {
114 shutdownDialog?.dismiss()
115 if (listNetworksAfterExit) openStartActivity()
116 finish()
117 }
118
119 fun stopVpn(@Suppress("UNUSED_PARAMETER") i: MenuItem? = null) {
120 refreshTimer?.cancel()
121 list_wrapper.isRefreshing = false
122 shutdownDialog = showProgressDialog(R.string.message_disconnecting_vpn)
123 TincVpnService.disconnect()
124 }
125
126 private fun writeNetworkInfo(cfg: VpnInterfaceConfiguration) {
107 text_network_name.text = TincVpnService.getCurrentNetName() ?: getString(R.string.value_none) 127 text_network_name.text = TincVpnService.getCurrentNetName() ?: getString(R.string.value_none)
108 text_network_ip_addresses.setText(cfg.addresses.map { it.toSlashSeparated() }) 128 text_network_ip_addresses.setText(cfg.addresses.map { it.toSlashSeparated() })
109 text_network_routes.setText(cfg.routes.map { it.toSlashSeparated() }) 129 text_network_routes.setText(cfg.routes.map { it.toSlashSeparated() })
@@ -116,28 +136,35 @@ class StatusActivity : BaseActivity(), AdapterView.OnItemClickListener, SwipeRef
116 text_network_disallowed_applications.setText(cfg.disallowedApplications) 136 text_network_disallowed_applications.setText(cfg.disallowedApplications)
117 } 137 }
118 138
119 fun updateNodeList() { 139 private fun writeNodeList(nodeList: List<String>) = runOnUiThread {
120 refreshTimer?.schedule(timerTask { 140 nodeListAdapter?.setElements(nodeList)
121 onRefresh() 141 node_list_placeholder.visibility = if (nodeListAdapter?.isEmpty != false) View.VISIBLE else View.GONE
122 if (updateView) updateNodeList() 142 list_wrapper.isRefreshing = false
123 }, REFRESH_RATE)
124 } 143 }
125 144
126 fun stopVpn(@Suppress("UNUSED_PARAMETER") i: MenuItem) { 145 private fun updateNodeList() {
127 TincVpnService.stopVpn() 146 getNodeNames().whenComplete { nodeList, _ -> runOnUiThread { writeNodeList(nodeList) } }
128 openStartActivity()
129 finish()
130 } 147 }
131 148
132 fun openStartActivity() = startActivity(Intent(this, StartActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)) 149 private fun updateView() = when {
150 TincVpnService.isConnected() -> updateNodeList()
151 else -> openStartActivity()
152 }
133 153
134 companion object { 154 private fun openStartActivity() {
135 private val REFRESH_RATE = 5000L 155 startActivity(Intent(this, StartActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
156 finish()
157 }
136 158
137 fun getNodeNames(): CompletableFuture<List<String>> = when (TincVpnService.isConnected()) { 159 companion object {
138 true -> Tinc.dumpNodes(TincVpnService.getCurrentNetName()!!).thenApply<List<String>> { it.map { it.substringBefore(' ') } }