aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/java/org/pacien/tincapp/activities/start/StartActivity.kt
blob: 7db0344d6adacb6df9fa7e997a06777a76fcd149 (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
130
131
132
133
134
/*
 * Tinc App, an Android binding and user interface for the tinc mesh VPN daemon
 * Copyright (C) 2017-2023 Pacien TRAN-GIRARD
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package org.pacien.tincapp.activities.start

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import android.view.Menu
import android.view.MenuItem
import kotlinx.android.synthetic.main.start_activity.*
import org.pacien.tincapp.R
import org.pacien.tincapp.activities.BaseActivity
import org.pacien.tincapp.activities.common.ProgressModal
import org.pacien.tincapp.activities.common.RecentCrashHandler
import org.pacien.tincapp.activities.configure.ConfigureActivity
import org.pacien.tincapp.activities.status.StatusActivity
import org.pacien.tincapp.context.App
import org.pacien.tincapp.intent.Actions
import org.pacien.tincapp.intent.BroadcastMapper
import org.pacien.tincapp.service.TincVpnService

/**
 * @author pacien
 */
class StartActivity : BaseActivity() {
  val permissionRequestCode = 0
  private val connectionStarter by lazy { ConnectionStarter(this) }
  private val recentCrashHandler by lazy { RecentCrashHandler(this) }
  private val broadcastMapper = BroadcastMapper(mapOf(
    Actions.EVENT_CONNECTED to this::onVpnStart,
    Actions.EVENT_ABORTED to this::onVpnStartError
  ))

  private var connectDialog: AlertDialog? = null

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.start_activity)
    initNetworkListFragment()

    if (intent.action == Actions.ACTION_CONNECT && intent.data?.schemeSpecificPart != null)
      connectionStarter.tryStart(intent.data!!.schemeSpecificPart, intent.data!!.fragment, false)
  }

  private fun initNetworkListFragment() {
    val fragment = start_activity_network_list_fragment as NetworkListFragment
    fragment.connectToNetworkAction = { netName -> connectToNetworkAction(netName) }
  }

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

  override fun onDestroy() {
    connectDialog?.dismiss()
    super.onDestroy()
  }

  override fun onResume() {
    super.onResume()
    if (TincVpnService.isConnected()) openStatusActivity(false)
    broadcastMapper.register()
    recentCrashHandler.handleRecentCrash()
  }

  override fun onPause() {
    broadcastMapper.unregister()
    super.onPause()
  }

  override fun onActivityResult(request: Int, result: Int, data: Intent?) {
    when (request) {
      permissionRequestCode -> continueConnectionStart(result)
      else -> throw IllegalArgumentException("Result for unknown request received.")
    }

    super.onActivityResult(request, result, data)
  }

  private fun connectToNetworkAction(netName: String) {
    if (connectDialog?.isShowing == true) return
    connectionStarter.tryStart(netName, displayStatus = true)
  }

  private fun continueConnectionStart(result: Int): Unit = when (result) {
    Activity.RESULT_OK -> connectionStarter.tryStart()
    else -> App.alert(R.string.notification_error_title_unable_to_start_tinc, getString(R.string.notification_error_message_could_not_bind_iface))
  }

  private fun onVpnStart() {
    connectDialog?.dismiss()
    if (connectionStarter.displayStatus()) openStatusActivity()
    finish()
  }

  private fun onVpnStartError() {
    connectDialog?.dismiss()
  }

  fun showConnectProgressDialog() {
    connectDialog = ProgressModal.show(this, resources.getString(R.string.start_starting_vpn))
  }

  @Suppress("UNUSED_PARAMETER")
  fun openConfigureActivity(m: MenuItem) =
    startActivity(Intent(this, ConfigureActivity::class.java))

  private fun openStatusActivity(transition: Boolean = true) {
    val intent = Intent(this, StatusActivity::class.java)
      .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
      .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
      .apply { if (!transition) addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION) }

    startActivity(intent)
  }
}