0
0
mirror of https://github.com/dovecoteescapee/ByeDPIAndroid.git synced 2025-07-01 19:13:00 +00:00

Move app status from MainActivity.kt to ByeDpiStatus.kt

This commit is contained in:
dovecoteescapee 2024-03-02 15:32:31 +03:00
parent 81d080863f
commit f9a2918271
6 changed files with 83 additions and 106 deletions

View File

@ -1,5 +1,6 @@
package io.github.dovecoteescapee.byedpi.activities package io.github.dovecoteescapee.byedpi.activities
import android.annotation.SuppressLint
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@ -28,6 +29,7 @@ import io.github.dovecoteescapee.byedpi.fragments.SettingsFragment
import io.github.dovecoteescapee.byedpi.databinding.ActivityMainBinding import io.github.dovecoteescapee.byedpi.databinding.ActivityMainBinding
import io.github.dovecoteescapee.byedpi.services.ByeDpiProxyService import io.github.dovecoteescapee.byedpi.services.ByeDpiProxyService
import io.github.dovecoteescapee.byedpi.services.ByeDpiVpnService import io.github.dovecoteescapee.byedpi.services.ByeDpiVpnService
import io.github.dovecoteescapee.byedpi.services.appStatus
import io.github.dovecoteescapee.byedpi.utility.getPreferences import io.github.dovecoteescapee.byedpi.utility.getPreferences
import io.github.dovecoteescapee.byedpi.utility.mode import io.github.dovecoteescapee.byedpi.utility.mode
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -40,9 +42,6 @@ class MainActivity : AppCompatActivity() {
companion object { companion object {
private val TAG: String = MainActivity::class.java.simpleName private val TAG: String = MainActivity::class.java.simpleName
private var status: AppStatus = AppStatus.Halted
private var mode: Mode = Mode.VPN
private fun collectLogs(): String? = private fun collectLogs(): String? =
try { try {
Runtime.getRuntime() Runtime.getRuntime()
@ -61,7 +60,7 @@ class MainActivity : AppCompatActivity() {
startVpn() startVpn()
} else { } else {
Toast.makeText(this, R.string.vpn_permission_denied, Toast.LENGTH_SHORT).show() Toast.makeText(this, R.string.vpn_permission_denied, Toast.LENGTH_SHORT).show()
updateStatus(AppStatus.Halted) updateStatus()
} }
} }
@ -111,22 +110,8 @@ class MainActivity : AppCompatActivity() {
} }
when (val action = intent.action) { when (val action = intent.action) {
STARTED_BROADCAST -> if ( STARTED_BROADCAST,
status == AppStatus.Halted || status == AppStatus.Starting STOPPED_BROADCAST -> updateStatus()
) {
updateStatus(AppStatus.Running, Mode.fromSender(sender))
} else {
Log.w(TAG, "Received STARTED while status is $status")
}
STOPPED_BROADCAST -> if (
mode == Mode.fromSender(sender) &&
(status == AppStatus.Running || status == AppStatus.Stopping)
) {
updateStatus(AppStatus.Halted)
} else {
Log.w(TAG, "Received STOPPED $sender while status is $status")
}
FAILED_BROADCAST -> { FAILED_BROADCAST -> {
Toast.makeText( Toast.makeText(
@ -134,7 +119,7 @@ class MainActivity : AppCompatActivity() {
getString(R.string.failed_to_start, sender.name), getString(R.string.failed_to_start, sender.name),
Toast.LENGTH_SHORT, Toast.LENGTH_SHORT,
).show() ).show()
updateStatus(AppStatus.Halted) updateStatus()
} }
else -> Log.w(TAG, "Unknown action: $action") else -> Log.w(TAG, "Unknown action: $action")
@ -154,6 +139,7 @@ class MainActivity : AppCompatActivity() {
addAction(FAILED_BROADCAST) addAction(FAILED_BROADCAST)
} }
@SuppressLint("UnspecifiedRegisterReceiverFlag")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
registerReceiver(receiver, intentFilter, RECEIVER_EXPORTED) registerReceiver(receiver, intentFilter, RECEIVER_EXPORTED)
} else { } else {
@ -161,12 +147,10 @@ class MainActivity : AppCompatActivity() {
} }
binding.statusButton.setOnClickListener { binding.statusButton.setOnClickListener {
val (status, _) = appStatus
when (status) { when (status) {
AppStatus.Halted -> start() AppStatus.Halted -> start()
AppStatus.Running -> stop() AppStatus.Running -> stop()
else -> {
// ignore
}
} }
} }
@ -190,8 +174,10 @@ class MainActivity : AppCompatActivity() {
return true return true
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean = override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) { val (status, _) = appStatus
return when (item.itemId) {
R.id.action_settings -> { R.id.action_settings -> {
if (status == AppStatus.Halted) { if (status == AppStatus.Halted) {
val intent = Intent(this, SettingsActivity::class.java) val intent = Intent(this, SettingsActivity::class.java)
@ -217,14 +203,11 @@ class MainActivity : AppCompatActivity() {
else -> super.onOptionsItemSelected(item) else -> super.onOptionsItemSelected(item)
} }
}
private fun start() { private fun start() {
// Starting and stopping is too fast when (getPreferences(this).mode()) {
// updateStatus(AppStatus.Starting) Mode.VPN -> {
val preferences = getPreferences(this)
when (val mode = preferences.getString("byedpi_mode", null) ?: "vpn") {
"vpn" -> {
val intentPrepare = VpnService.prepare(this) val intentPrepare = VpnService.prepare(this)
if (intentPrepare != null) { if (intentPrepare != null) {
vpnRegister.launch(intentPrepare) vpnRegister.launch(intentPrepare)
@ -233,8 +216,7 @@ class MainActivity : AppCompatActivity() {
} }
} }
"proxy" -> startProxy() Mode.Proxy -> startProxy()
else -> Log.e(TAG, "Unknown mode: $mode")
} }
} }
@ -253,8 +235,7 @@ class MainActivity : AppCompatActivity() {
} }
private fun stop() { private fun stop() {
// Starting and stopping is too fast val (_, mode) = appStatus
// updateStatus(AppStatus.Stopping)
when (mode) { when (mode) {
Mode.VPN -> stopVpn() Mode.VPN -> stopVpn()
Mode.Proxy -> stopProxy() Mode.Proxy -> stopProxy()
@ -275,13 +256,10 @@ class MainActivity : AppCompatActivity() {
startService(intent) startService(intent)
} }
private fun updateStatus( private fun updateStatus() {
status: AppStatus = MainActivity.status, val (status, mode) = appStatus
mode: Mode = MainActivity.mode,
) {
Log.i(TAG, "Updating from ${MainActivity.status} to $status")
MainActivity.mode = mode Log.i(TAG, "Updating status: $status, $mode")
val preferences = getPreferences(this) val preferences = getPreferences(this)
val proxyIp = preferences.getString("byedpi_proxy_ip", null) ?: "127.0.0.1" val proxyIp = preferences.getString("byedpi_proxy_ip", null) ?: "127.0.0.1"
@ -290,9 +268,7 @@ class MainActivity : AppCompatActivity() {
when (status) { when (status) {
AppStatus.Halted -> { AppStatus.Halted -> {
val newMode = preferences.mode() when (preferences.mode()) {
MainActivity.mode = newMode
when (newMode) {
Mode.VPN -> { Mode.VPN -> {
binding.statusText.setText(R.string.vpn_disconnected) binding.statusText.setText(R.string.vpn_disconnected)
binding.statusButton.setText(R.string.vpn_connect) binding.statusButton.setText(R.string.vpn_connect)
@ -303,7 +279,6 @@ class MainActivity : AppCompatActivity() {
binding.statusButton.setText(R.string.proxy_start) binding.statusButton.setText(R.string.proxy_start)
} }
} }
MainActivity.status = AppStatus.Halted
binding.statusButton.isEnabled = true binding.statusButton.isEnabled = true
} }
@ -319,41 +294,8 @@ class MainActivity : AppCompatActivity() {
binding.statusButton.setText(R.string.proxy_stop) binding.statusButton.setText(R.string.proxy_stop)
} }
} }
MainActivity.status = AppStatus.Running
binding.statusButton.isEnabled = true binding.statusButton.isEnabled = true
} }
AppStatus.Starting -> {
if (MainActivity.status == AppStatus.Halted) {
when (mode) {
Mode.VPN -> {
binding.statusText.setText(R.string.vpn_connecting)
}
Mode.Proxy -> {
binding.statusText.setText(R.string.proxy_starting)
}
}
MainActivity.status = AppStatus.Starting
binding.statusButton.isEnabled = false
}
}
AppStatus.Stopping -> {
if (MainActivity.status == AppStatus.Running) {
when (mode) {
Mode.VPN -> {
binding.statusText.setText(R.string.vpn_disconnecting)
}
Mode.Proxy -> {
binding.statusText.setText(R.string.proxy_stopping)
}
}
MainActivity.status = AppStatus.Stopping
binding.statusButton.isEnabled = false
}
}
} }
} }
} }

View File

@ -3,8 +3,6 @@ package io.github.dovecoteescapee.byedpi.data
enum class AppStatus { enum class AppStatus {
Halted, Halted,
Running, Running,
Starting,
Stopping,
} }
enum class Mode { enum class Mode {

View File

@ -1,7 +1,7 @@
package io.github.dovecoteescapee.byedpi.data package io.github.dovecoteescapee.byedpi.data
enum class ServiceStatus { enum class ServiceStatus {
DISCONNECTED, Disconnected,
CONNECTED, Connected,
FAILED, Failed,
} }

View File

@ -10,9 +10,11 @@ import androidx.lifecycle.lifecycleScope
import io.github.dovecoteescapee.byedpi.R import io.github.dovecoteescapee.byedpi.R
import io.github.dovecoteescapee.byedpi.core.ByeDpiProxy import io.github.dovecoteescapee.byedpi.core.ByeDpiProxy
import io.github.dovecoteescapee.byedpi.core.ByeDpiProxyPreferences import io.github.dovecoteescapee.byedpi.core.ByeDpiProxyPreferences
import io.github.dovecoteescapee.byedpi.data.AppStatus
import io.github.dovecoteescapee.byedpi.data.START_ACTION import io.github.dovecoteescapee.byedpi.data.START_ACTION
import io.github.dovecoteescapee.byedpi.data.STOP_ACTION import io.github.dovecoteescapee.byedpi.data.STOP_ACTION
import io.github.dovecoteescapee.byedpi.data.FAILED_BROADCAST import io.github.dovecoteescapee.byedpi.data.FAILED_BROADCAST
import io.github.dovecoteescapee.byedpi.data.Mode
import io.github.dovecoteescapee.byedpi.data.SENDER import io.github.dovecoteescapee.byedpi.data.SENDER
import io.github.dovecoteescapee.byedpi.data.STARTED_BROADCAST import io.github.dovecoteescapee.byedpi.data.STARTED_BROADCAST
import io.github.dovecoteescapee.byedpi.data.STOPPED_BROADCAST import io.github.dovecoteescapee.byedpi.data.STOPPED_BROADCAST
@ -39,7 +41,7 @@ class ByeDpiProxyService : LifecycleService() {
private const val NOTIFICATION_CHANNEL_ID: String = "ByeDPI Proxy" private const val NOTIFICATION_CHANNEL_ID: String = "ByeDPI Proxy"
@Volatile @Volatile
private var status: ServiceStatus = ServiceStatus.DISCONNECTED private var status: ServiceStatus = ServiceStatus.Disconnected
} }
override fun onCreate() { override fun onCreate() {
@ -74,7 +76,7 @@ class ByeDpiProxyService : LifecycleService() {
private suspend fun start() { private suspend fun start() {
Log.i(TAG, "Starting") Log.i(TAG, "Starting")
if (status == ServiceStatus.CONNECTED) { if (status == ServiceStatus.Connected) {
Log.w(TAG, "Proxy already connected") Log.w(TAG, "Proxy already connected")
return return
} }
@ -83,11 +85,11 @@ class ByeDpiProxyService : LifecycleService() {
mutex.withLock { mutex.withLock {
startProxy() startProxy()
} }
updateStatus(ServiceStatus.CONNECTED) updateStatus(ServiceStatus.Connected)
startForeground() startForeground()
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Failed to start proxy", e) Log.e(TAG, "Failed to start proxy", e)
updateStatus(ServiceStatus.FAILED) updateStatus(ServiceStatus.Failed)
stop() stop()
} }
} }
@ -111,7 +113,7 @@ class ByeDpiProxyService : LifecycleService() {
mutex.withLock { mutex.withLock {
stopProxy() stopProxy()
} }
updateStatus(ServiceStatus.DISCONNECTED) updateStatus(ServiceStatus.Disconnected)
stopSelf() stopSelf()
} }
@ -132,9 +134,9 @@ class ByeDpiProxyService : LifecycleService() {
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
if (code != 0) { if (code != 0) {
Log.e(TAG, "Proxy stopped with code $code") Log.e(TAG, "Proxy stopped with code $code")
updateStatus(ServiceStatus.FAILED) updateStatus(ServiceStatus.Failed)
} else { } else {
updateStatus(ServiceStatus.DISCONNECTED) updateStatus(ServiceStatus.Disconnected)
} }
} }
} }
@ -145,7 +147,7 @@ class ByeDpiProxyService : LifecycleService() {
private suspend fun stopProxy() { private suspend fun stopProxy() {
Log.i(TAG, "Stopping proxy") Log.i(TAG, "Stopping proxy")
if (status == ServiceStatus.DISCONNECTED) { if (status == ServiceStatus.Disconnected) {
Log.w(TAG, "Proxy already disconnected") Log.w(TAG, "Proxy already disconnected")
return return
} }
@ -164,11 +166,21 @@ class ByeDpiProxyService : LifecycleService() {
Log.d(TAG, "Proxy status changed from $status to $newStatus") Log.d(TAG, "Proxy status changed from $status to $newStatus")
status = newStatus status = newStatus
setStatus(
when (newStatus) {
ServiceStatus.Connected -> AppStatus.Running
ServiceStatus.Disconnected,
ServiceStatus.Failed -> AppStatus.Halted
},
Mode.Proxy
)
val intent = Intent( val intent = Intent(
when (newStatus) { when (newStatus) {
ServiceStatus.CONNECTED -> STARTED_BROADCAST ServiceStatus.Connected -> STARTED_BROADCAST
ServiceStatus.DISCONNECTED -> STOPPED_BROADCAST ServiceStatus.Disconnected -> STOPPED_BROADCAST
ServiceStatus.FAILED -> FAILED_BROADCAST ServiceStatus.Failed -> FAILED_BROADCAST
} }
) )
intent.putExtra(SENDER, Sender.Proxy.ordinal) intent.putExtra(SENDER, Sender.Proxy.ordinal)

View File

@ -0,0 +1,13 @@
package io.github.dovecoteescapee.byedpi.services
import io.github.dovecoteescapee.byedpi.data.AppStatus
import io.github.dovecoteescapee.byedpi.data.Mode
@Volatile
var appStatus = AppStatus.Halted to Mode.VPN
private set
fun setStatus(status: AppStatus, mode: Mode) {
appStatus = status to mode
}

View File

@ -15,9 +15,11 @@ import io.github.dovecoteescapee.byedpi.R
import io.github.dovecoteescapee.byedpi.activities.MainActivity import io.github.dovecoteescapee.byedpi.activities.MainActivity
import io.github.dovecoteescapee.byedpi.core.ByeDpiProxy import io.github.dovecoteescapee.byedpi.core.ByeDpiProxy
import io.github.dovecoteescapee.byedpi.core.ByeDpiProxyPreferences import io.github.dovecoteescapee.byedpi.core.ByeDpiProxyPreferences
import io.github.dovecoteescapee.byedpi.data.AppStatus
import io.github.dovecoteescapee.byedpi.data.START_ACTION import io.github.dovecoteescapee.byedpi.data.START_ACTION
import io.github.dovecoteescapee.byedpi.data.STOP_ACTION import io.github.dovecoteescapee.byedpi.data.STOP_ACTION
import io.github.dovecoteescapee.byedpi.data.FAILED_BROADCAST import io.github.dovecoteescapee.byedpi.data.FAILED_BROADCAST
import io.github.dovecoteescapee.byedpi.data.Mode
import io.github.dovecoteescapee.byedpi.data.SENDER import io.github.dovecoteescapee.byedpi.data.SENDER
import io.github.dovecoteescapee.byedpi.data.STARTED_BROADCAST import io.github.dovecoteescapee.byedpi.data.STARTED_BROADCAST
import io.github.dovecoteescapee.byedpi.data.STOPPED_BROADCAST import io.github.dovecoteescapee.byedpi.data.STOPPED_BROADCAST
@ -46,7 +48,7 @@ class ByeDpiVpnService : LifecycleVpnService() {
private const val NOTIFICATION_CHANNEL_ID: String = "ByeDPIVpn" private const val NOTIFICATION_CHANNEL_ID: String = "ByeDPIVpn"
@Volatile @Volatile
private var status: ServiceStatus = ServiceStatus.DISCONNECTED private var status: ServiceStatus = ServiceStatus.Disconnected
} }
override fun onCreate() { override fun onCreate() {
@ -86,7 +88,7 @@ class ByeDpiVpnService : LifecycleVpnService() {
private suspend fun start() { private suspend fun start() {
Log.i(TAG, "Starting") Log.i(TAG, "Starting")
if (status == ServiceStatus.CONNECTED) { if (status == ServiceStatus.Connected) {
Log.w(TAG, "VPN already connected") Log.w(TAG, "VPN already connected")
return return
} }
@ -96,11 +98,11 @@ class ByeDpiVpnService : LifecycleVpnService() {
startProxy() startProxy()
startTun2Socks() startTun2Socks()
} }
updateStatus(ServiceStatus.CONNECTED) updateStatus(ServiceStatus.Connected)
startForeground() startForeground()
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Failed to start VPN", e) Log.e(TAG, "Failed to start VPN", e)
updateStatus(ServiceStatus.FAILED) updateStatus(ServiceStatus.Failed)
stop() stop()
} }
} }
@ -133,7 +135,7 @@ class ByeDpiVpnService : LifecycleVpnService() {
} }
} }
updateStatus(ServiceStatus.DISCONNECTED) updateStatus(ServiceStatus.Disconnected)
stopSelf() stopSelf()
} }
@ -153,11 +155,11 @@ class ByeDpiVpnService : LifecycleVpnService() {
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
if (code != 0) { if (code != 0) {
Log.e(TAG, "Proxy stopped with code $code") Log.e(TAG, "Proxy stopped with code $code")
updateStatus(ServiceStatus.FAILED) updateStatus(ServiceStatus.Failed)
} else { } else {
if (!stopping) { if (!stopping) {
stop() stop()
updateStatus(ServiceStatus.DISCONNECTED) updateStatus(ServiceStatus.Disconnected)
} }
} }
} }
@ -169,7 +171,7 @@ class ByeDpiVpnService : LifecycleVpnService() {
private suspend fun stopProxy() { private suspend fun stopProxy() {
Log.i(TAG, "Stopping proxy") Log.i(TAG, "Stopping proxy")
if (status == ServiceStatus.DISCONNECTED) { if (status == ServiceStatus.Disconnected) {
Log.w(TAG, "Proxy already disconnected") Log.w(TAG, "Proxy already disconnected")
return return
} }
@ -218,11 +220,21 @@ class ByeDpiVpnService : LifecycleVpnService() {
Log.d(TAG, "VPN status changed from $status to $newStatus") Log.d(TAG, "VPN status changed from $status to $newStatus")
status = newStatus status = newStatus
setStatus(
when (newStatus) {
ServiceStatus.Connected -> AppStatus.Running
ServiceStatus.Disconnected,
ServiceStatus.Failed -> AppStatus.Halted
},
Mode.VPN
)
val intent = Intent( val intent = Intent(
when (newStatus) { when (newStatus) {
ServiceStatus.CONNECTED -> STARTED_BROADCAST ServiceStatus.Connected -> STARTED_BROADCAST
ServiceStatus.DISCONNECTED -> STOPPED_BROADCAST ServiceStatus.Disconnected -> STOPPED_BROADCAST
ServiceStatus.FAILED -> FAILED_BROADCAST ServiceStatus.Failed -> FAILED_BROADCAST
} }
) )
intent.putExtra(SENDER, Sender.VPN.ordinal) intent.putExtra(SENDER, Sender.VPN.ordinal)