aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/src/main/AndroidManifest.xml4
-rw-r--r--app/src/main/java/org/pacien/tincapp/activities/StartActivity.kt204
-rw-r--r--app/src/main/java/org/pacien/tincapp/activities/start/ConnectionStarter.kt69
-rw-r--r--app/src/main/java/org/pacien/tincapp/activities/start/NetworkListFragment.kt84
-rw-r--r--app/src/main/java/org/pacien/tincapp/activities/start/NetworkListLiveData.kt46
-rw-r--r--app/src/main/java/org/pacien/tincapp/activities/start/NetworkListViewModel.kt28
-rw-r--r--app/src/main/java/org/pacien/tincapp/activities/start/StartActivity.kt117
-rw-r--r--app/src/main/java/org/pacien/tincapp/activities/status/StatusActivity.kt2
-rw-r--r--app/src/main/java/org/pacien/tincapp/activities/status/nodes/NodeListFragment.kt2
-rw-r--r--app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt2
-rw-r--r--app/src/main/res/layout/start_activity.xml (renamed from app/src/main/res/layout/fragment_network_list_header.xml)19
-rw-r--r--app/src/main/res/layout/start_network_list.xml50
-rw-r--r--app/src/main/res/layout/start_network_list_header.xml (renamed from app/src/main/res/layout/fragment_list_view.xml)18
-rw-r--r--app/src/main/res/layout/start_network_list_item.xml (renamed from app/src/main/res/layout/fragment_list_item.xml)3
-rw-r--r--app/src/main/res/layout/status_node_list.xml2
-rw-r--r--app/src/main/res/layout/status_node_list_item.xml27
-rw-r--r--app/src/main/res/menu/menu_start.xml2
-rw-r--r--app/src/main/res/values-ja/strings.xml2
-rw-r--r--app/src/main/res/values-nb-rNO/strings.xml2
-rw-r--r--app/src/main/res/values-zh-rCN/strings.xml4
-rw-r--r--app/src/main/res/values-zh-rHK/strings.xml4
-rw-r--r--app/src/main/res/values-zh-rTW/strings.xml4
-rw-r--r--app/src/main/res/values/strings.xml8
23 files changed, 453 insertions, 250 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 054438e..70839b7 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -34,7 +34,7 @@
34 tools:ignore="GoogleAppIndexingWarning"> 34 tools:ignore="GoogleAppIndexingWarning">
35 35
36 <activity 36 <activity
37 android:name=".activities.StartActivity" 37 android:name=".activities.start.StartActivity"
38 android:configChanges="orientation|screenSize" 38 android:configChanges="orientation|screenSize"
39 android:label="@string/app_name"> 39 android:label="@string/app_name">
40 <intent-filter> 40 <intent-filter>
@@ -51,7 +51,7 @@
51 <activity 51 <activity
52 android:name=".activities.configure.ConfigureActivity" 52 android:name=".activities.configure.ConfigureActivity"
53 android:configChanges="orientation|screenSize" 53 android:configChanges="orientation|screenSize"
54 android:parentActivityName=".activities.StartActivity"> 54 android:parentActivityName=".activities.start.StartActivity">
55 </activity> 55 </activity>
56 56
57 <activity 57 <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
deleted file mode 100644
index 7023316..0000000
--- a/app/src/main/java/org/pacien/tincapp/activities/StartActivity.kt
+++ /dev/null
@@ -1,204 +0,0 @@
1/*
2 * Tinc App, an Android binding and user interface for the tinc mesh VPN daemon
3 * Copyright (C) 2017-2018 Pacien TRAN-GIRARD
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19package org.pacien.tincapp.activities
20
21import android.app.Activity
22import android.content.Intent
23import android.net.VpnService
24import android.os.Bundle
25import android.support.v4.widget.SwipeRefreshLayout
26import android.support.v7.app.AlertDialog
27import android.view.Menu
28import android.view.MenuItem
29import android.view.View
30import android.widget.AdapterView
31import android.widget.ArrayAdapter
32import android.widget.TextView
33import kotlinx.android.synthetic.main.base.*
34import kotlinx.android.synthetic.main.dialog_decrypt_keys.view.*
35import kotlinx.android.synthetic.main.fragment_list_view.*
36import kotlinx.android.synthetic.main.fragment_network_list_header.*
37import org.pacien.tincapp.R
38import org.pacien.tincapp.activities.common.ProgressModal
39import org.pacien.tincapp.activities.configure.ConfigureActivity
40import org.pacien.tincapp.activities.status.StatusActivity
41import org.pacien.tincapp.context.AppPaths
42import org.pacien.tincapp.extensions.setElements
43import org.pacien.tincapp.intent.Actions
44import org.pacien.tincapp.intent.BroadcastMapper
45import org.pacien.tincapp.service.TincVpnService
46import org.pacien.tincapp.utils.TincKeyring
47
48/**
49 * @author pacien
50 */
51class StartActivity : BaseActivity() {
52 companion object {
53 private const val PERMISSION_REQUEST = 0
54 }
55
56 private val networkList = object : AdapterView.OnItemClickListener, SwipeRefreshLayout.OnRefreshListener {
57 private var networkListAdapter: ArrayAdapter<String>? = null
58
59 fun init() {
60 networkListAdapter = ArrayAdapter(this@StartActivity, R.layout.fragment_list_item)
61 layoutInflater.inflate(R.layout.fragment_list_view, main_content)
62 list_wrapper.setOnRefreshListener(this)
63 list.addHeaderView(layoutInflater.inflate(R.layout.fragment_network_list_header, list, false), null, false)
64 list.addFooterView(View(this@StartActivity), null, false)
65 list.adapter = networkListAdapter
66 list.onItemClickListener = this
67 }
68
69 fun destroy() {
70 networkListAdapter = null
71 }
72
73 override fun onRefresh() {
74 val networks = AppPaths.confDir().list()?.sorted() ?: emptyList()
75 runOnUiThread {
76 networkListAdapter?.setElements(networks)
77 setPlaceholderVisibility()
78 list_wrapper.isRefreshing = false
79 }
80 }
81
82 override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
83 connectionStarter.tryStart(netName = (view as TextView).text.toString(), displayStatus = true)
84 }
85
86 private fun setPlaceholderVisibility() = if (networkListAdapter?.isEmpty != false) {
87 network_list_placeholder.text = getListPlaceholderText()
88 network_list_placeholder.visibility = View.VISIBLE
89 } else {
90 network_list_placeholder.visibility = View.GONE
91 }
92
93 private fun getListPlaceholderText() = if (!AppPaths.storageAvailable()) {
94 getText(R.string.message_storage_unavailable)
95 } else {
96 getText(R.string.message_no_network_configuration_found)
97 }
98 }
99
100 private val connectionStarter = object {
101 private var netName: String? = null
102 private var passphrase: String? = null
103 private var displayStatus = false
104
105 fun displayStatus() = displayStatus
106
107 fun tryStart(netName: String? = null, passphrase: String? = null, displayStatus: Boolean? = null) {
108 if (netName != null) this.netName = netName
109 this.passphrase = passphrase
110 if (displayStatus != null) this.displayStatus = displayStatus
111
112 val permissionRequestIntent = VpnService.prepare(this@StartActivity)
113 if (permissionRequestIntent != null)
114 return startActivityForResult(permissionRequestIntent, PERMISSION_REQUEST)
115
116 if (TincKeyring.needsPassphrase(this.netName!!) && this.passphrase == null)
117 return askForPassphrase()
118
119 startVpn(this.netName!!, this.passphrase)
120 }
121
122 private fun askForPassphrase() {
123 layoutInflater.inflate(R.layout.dialog_decrypt_keys, main_content, false).let { dialog ->
124 AlertDialog.Builder(this@StartActivity)
125 .setTitle(R.string.title_unlock_private_keys).setView(dialog)
126 .setPositiveButton(R.string.action_unlock) { _, _ -> tryStart(passphrase = dialog.passphrase.text.toString()) }
127 .setNegativeButton(R.string.action_cancel) { _, _ -> Unit }
128 .show()
129 }
130 }
131
132 private fun startVpn(netName: String, passphrase: String? = null) {
133 connectDialog = ProgressModal.show(this@StartActivity, getString(R.string.message_starting_vpn))
134 TincVpnService.connect(netName, passphrase)
135 }
136 }
137
138 private val broadcastMapper = BroadcastMapper(mapOf(
139 Actions.EVENT_CONNECTED to this::onVpnStart,
140 Actions.EVENT_ABORTED to this::onVpnStartError))
141
142 private var connectDialog: AlertDialog? = null
143
144 override fun onCreate(savedInstanceState: Bundle?) {