aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/java/org/pacien/tincapp/activities/StatusActivity.kt
blob: b4ba7dda19712875390dd76ce0f065626696bab4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package org.pacien.tincapp.activities

import android.content.Intent
import android.os.Bundle
import android.support.v4.widget.SwipeRefreshLayout
import android.support.v7.app.AlertDialog
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.TextView
import kotlinx.android.synthetic.main.base.*
import kotlinx.android.synthetic.main.dialog_text_monopsace.view.*
import kotlinx.android.synthetic.main.fragment_network_status_header.*
import kotlinx.android.synthetic.main.page_status.*
import org.pacien.tincapp.R
import org.pacien.tincapp.commands.Tinc
import org.pacien.tincapp.service.TincVpnService
import org.pacien.tincapp.service.VpnInterfaceConfiguration
import org.pacien.tincapp.utils.setElements
import org.pacien.tincapp.utils.setText
import java.util.*
import kotlin.concurrent.timerTask

/**
 * @author pacien
 */
class StatusActivity : BaseActivity(), AdapterView.OnItemClickListener, SwipeRefreshLayout.OnRefreshListener {

    private var nodeListAdapter: ArrayAdapter<String>? = null
    private var refreshTimer: Timer? = null
    private var updateView: Boolean = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        nodeListAdapter = ArrayAdapter<String>(this, R.layout.fragment_list_item)
        refreshTimer = Timer(true)

        layoutInflater.inflate(R.layout.page_status, main_content)
        node_list_wrapper.setOnRefreshListener(this)
        node_list.addHeaderView(layoutInflater.inflate(R.layout.fragment_network_status_header, node_list, false), null, false)
        node_list.addFooterView(View(this), null, false)
        node_list.emptyView = node_list_empty
        node_list.onItemClickListener = this
        node_list.adapter = nodeListAdapter
    }

    override fun onCreateOptionsMenu(m: Menu): Boolean {
        menuInflater.inflate(R.menu.menu_status, m)
        return super.onCreateOptionsMenu(m)
    }

    override fun onDestroy() {
        super.onDestroy()
        refreshTimer?.cancel()
        nodeListAdapter = null
        refreshTimer = null
    }

    override fun onStart() {
        super.onStart()
        writeNetworkInfo(TincVpnService.getCurrentInterfaceCfg() ?: VpnInterfaceConfiguration())
        updateView = true
        onRefresh()
        updateNodeList()
    }

    override fun onStop() {
        super.onStop()
        updateView = false
    }

    override fun onRefresh() {
        val nodes = getNodeNames()
        runOnUiThread {
            nodeListAdapter?.setElements(nodes)
            node_list_wrapper.isRefreshing = false
        }
    }

    override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
        val nodeName = (view as TextView).text.toString()
        val dialogTextView = layoutInflater.inflate(R.layout.dialog_text_monopsace, main_content, false)
        dialogTextView.dialog_text_monospace.text = Tinc.info(TincVpnService.getCurrentNetName()!!, nodeName)

        AlertDialog.Builder(this)
                .setTitle(R.string.title_node_info)
                .setView(dialogTextView)
                .setPositiveButton(R.string.action_close) { _, _ -> /* nop */ }
                .show()
    }

    fun writeNetworkInfo(cfg: VpnInterfaceConfiguration) {
        text_network_name.text = TincVpnService.getCurrentNetName() ?: getString(R.string.value_none)
        text_network_ip_addresses.setText(cfg.addresses.map { it.toString() })
        text_network_routes.setText(cfg.routes.map { it.toString() })
        text_network_dns_servers.setText(cfg.dnsServers)
        text_network_search_domains.setText(cfg.searchDomains)
        text_network_allow_bypass.text = getString(if (cfg.allowBypass) R.string.value_yes else R.string.value_no)
        block_network_allowed_applications.visibility = if (cfg.allowedApplications.isNotEmpty()) View.VISIBLE else View.GONE
        text_network_allowed_applications.setText(cfg.allowedApplications)
        block_network_disallowed_applications.visibility = if (cfg.disallowedApplications.isNotEmpty()) View.VISIBLE else View.GONE
        text_network_disallowed_applications.setText(cfg.disallowedApplications)
    }

    fun updateNodeList() {
        refreshTimer?.schedule(timerTask {
            onRefresh()
            if (updateView) updateNodeList()
        }, REFRESH_RATE)
    }

    fun stopVpn(@Suppress("UNUSED_PARAMETER") i: MenuItem) {
        TincVpnService.stopVpn()
        startActivity(Intent(this, StartActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
        finish()
    }

    companion object {
        private val REFRESH_RATE = 5000L

        fun getNodeNames() =
                if (TincVpnService.isConnected()) Tinc.dumpNodes(TincVpnService.getCurrentNetName()!!).map { it.substringBefore(" ") }
                else emptyList()
    }

}