parent
f6175c2c69
commit
3e02dfef63
22 changed files with 577 additions and 154 deletions
|
|
@ -143,7 +143,7 @@ class AmneziaActivity : QtActivity() {
|
|||
*/
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
Log.v(TAG, "Create Amnezia activity: $intent")
|
||||
Log.d(TAG, "Create Amnezia activity: $intent")
|
||||
mainScope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
|
||||
vpnServiceMessenger = IpcMessenger(
|
||||
onDeadObjectException = ::doUnbindService,
|
||||
|
|
@ -154,7 +154,7 @@ class AmneziaActivity : QtActivity() {
|
|||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
Log.v(TAG, "onNewIntent: $intent")
|
||||
Log.d(TAG, "onNewIntent: $intent")
|
||||
intent?.let(::processIntent)
|
||||
}
|
||||
|
||||
|
|
@ -174,7 +174,7 @@ class AmneziaActivity : QtActivity() {
|
|||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
Log.v(TAG, "Start Amnezia activity")
|
||||
Log.d(TAG, "Start Amnezia activity")
|
||||
mainScope.launch {
|
||||
qtInitialized.await()
|
||||
doBindService()
|
||||
|
|
@ -182,13 +182,13 @@ class AmneziaActivity : QtActivity() {
|
|||
}
|
||||
|
||||
override fun onStop() {
|
||||
Log.v(TAG, "Stop Amnezia activity")
|
||||
Log.d(TAG, "Stop Amnezia activity")
|
||||
doUnbindService()
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
Log.v(TAG, "Destroy Amnezia activity")
|
||||
Log.d(TAG, "Destroy Amnezia activity")
|
||||
mainScope.cancel()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
|
@ -217,7 +217,7 @@ class AmneziaActivity : QtActivity() {
|
|||
CHECK_VPN_PERMISSION_ACTION_CODE -> {
|
||||
when (resultCode) {
|
||||
RESULT_OK -> {
|
||||
Log.v(TAG, "Vpn permission granted")
|
||||
Log.d(TAG, "Vpn permission granted")
|
||||
Toast.makeText(this, "Vpn permission granted", Toast.LENGTH_LONG).show()
|
||||
checkVpnPermissionCallbacks?.run { onSuccess() }
|
||||
}
|
||||
|
|
@ -240,7 +240,7 @@ class AmneziaActivity : QtActivity() {
|
|||
*/
|
||||
@MainThread
|
||||
private fun doBindService() {
|
||||
Log.v(TAG, "Bind service")
|
||||
Log.d(TAG, "Bind service")
|
||||
Intent(this, AmneziaVpnService::class.java).also {
|
||||
bindService(it, serviceConnection, BIND_ABOVE_CLIENT)
|
||||
}
|
||||
|
|
@ -251,7 +251,7 @@ class AmneziaActivity : QtActivity() {
|
|||
@MainThread
|
||||
private fun doUnbindService() {
|
||||
if (isInBoundState) {
|
||||
Log.v(TAG, "Unbind service")
|
||||
Log.d(TAG, "Unbind service")
|
||||
isWaitingStatus = true
|
||||
QtAndroidController.onServiceDisconnected()
|
||||
vpnServiceMessenger.reset()
|
||||
|
|
@ -286,7 +286,7 @@ class AmneziaActivity : QtActivity() {
|
|||
|
||||
@MainThread
|
||||
private fun checkVpnPermission(onSuccess: () -> Unit, onFail: () -> Unit) {
|
||||
Log.v(TAG, "Check VPN permission")
|
||||
Log.d(TAG, "Check VPN permission")
|
||||
VpnService.prepare(applicationContext)?.let {
|
||||
checkVpnPermissionCallbacks = CheckVpnPermissionCallbacks(onSuccess, onFail)
|
||||
startActivityForResult(it, CHECK_VPN_PERMISSION_ACTION_CODE)
|
||||
|
|
@ -307,7 +307,7 @@ class AmneziaActivity : QtActivity() {
|
|||
}
|
||||
|
||||
private fun connectToVpn(vpnConfig: String) {
|
||||
Log.v(TAG, "Connect to VPN")
|
||||
Log.d(TAG, "Connect to VPN")
|
||||
vpnServiceMessenger.send {
|
||||
Action.CONNECT.packToMessage {
|
||||
putString(VPN_CONFIG, vpnConfig)
|
||||
|
|
@ -316,7 +316,7 @@ class AmneziaActivity : QtActivity() {
|
|||
}
|
||||
|
||||
private fun startVpnService(vpnConfig: String) {
|
||||
Log.v(TAG, "Start VPN service")
|
||||
Log.d(TAG, "Start VPN service")
|
||||
Intent(this, AmneziaVpnService::class.java).apply {
|
||||
putExtra(VPN_CONFIG, vpnConfig)
|
||||
}.also {
|
||||
|
|
@ -325,7 +325,7 @@ class AmneziaActivity : QtActivity() {
|
|||
}
|
||||
|
||||
private fun disconnectFromVpn() {
|
||||
Log.v(TAG, "Disconnect from VPN")
|
||||
Log.d(TAG, "Disconnect from VPN")
|
||||
vpnServiceMessenger.send(Action.DISCONNECT)
|
||||
}
|
||||
|
||||
|
|
@ -369,7 +369,7 @@ class AmneziaActivity : QtActivity() {
|
|||
|
||||
@Suppress("unused")
|
||||
fun saveFile(fileName: String, data: String) {
|
||||
Log.v(TAG, "Save file $fileName")
|
||||
Log.d(TAG, "Save file $fileName")
|
||||
mainScope.launch {
|
||||
tmpFileContentToSave = data
|
||||
|
||||
|
|
@ -397,7 +397,7 @@ class AmneziaActivity : QtActivity() {
|
|||
|
||||
Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
Log.d(TAG, "File mimyType filter: $mimeTypes")
|
||||
Log.v(TAG, "File mimyType filter: $mimeTypes")
|
||||
when (mimeTypes.size) {
|
||||
1 -> type = mimeTypes.first()
|
||||
|
||||
|
|
@ -416,13 +416,6 @@ class AmneziaActivity : QtActivity() {
|
|||
@Suppress("unused")
|
||||
fun setNotificationText(title: String, message: String, timerSec: Int) {
|
||||
Log.v(TAG, "Set notification text")
|
||||
Log.w(TAG, "Not yet implemented")
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun cleanupLogs() {
|
||||
Log.v(TAG, "Cleanup logs")
|
||||
Log.w(TAG, "Not yet implemented")
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
|
|
@ -432,4 +425,29 @@ class AmneziaActivity : QtActivity() {
|
|||
startActivity(it)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun setSaveLogs(enabled: Boolean) {
|
||||
Log.d(TAG, "Set save logs: $enabled")
|
||||
mainScope.launch {
|
||||
Log.saveLogs = enabled
|
||||
vpnServiceMessenger.send {
|
||||
Action.SET_SAVE_LOGS.packToMessage {
|
||||
putBoolean(SAVE_LOGS, enabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun exportLogsFile(fileName: String) {
|
||||
Log.v(TAG, "Export logs file")
|
||||
saveFile(fileName, Log.getLogs())
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun clearLogs() {
|
||||
Log.v(TAG, "Clear logs")
|
||||
Log.clearLogs()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,14 +5,20 @@ import androidx.camera.core.CameraSelector
|
|||
import androidx.camera.core.CameraXConfig
|
||||
import androidx.core.app.NotificationChannelCompat.Builder
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import org.amnezia.vpn.util.Log
|
||||
import org.amnezia.vpn.util.Prefs
|
||||
import org.qtproject.qt.android.bindings.QtApplication
|
||||
|
||||
private const val TAG = "AmneziaApplication"
|
||||
const val NOTIFICATION_CHANNEL_ID: String = "org.amnezia.vpn.notification"
|
||||
|
||||
class AmneziaApplication : QtApplication(), CameraXConfig.Provider {
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
Prefs.init(this)
|
||||
Log.init(this)
|
||||
Log.d(TAG, "Create Amnezia application")
|
||||
createNotificationChannel()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ import org.amnezia.vpn.protocol.putStatistics
|
|||
import org.amnezia.vpn.protocol.putStatus
|
||||
import org.amnezia.vpn.protocol.wireguard.Wireguard
|
||||
import org.amnezia.vpn.util.Log
|
||||
import org.amnezia.vpn.util.Prefs
|
||||
import org.amnezia.vpn.util.net.NetworkState
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
|
|
@ -58,6 +59,8 @@ private const val TAG = "AmneziaVpnService"
|
|||
|
||||
const val VPN_CONFIG = "VPN_CONFIG"
|
||||
const val ERROR_MSG = "ERROR_MSG"
|
||||
const val SAVE_LOGS = "SAVE_LOGS"
|
||||
|
||||
const val AFTER_PERMISSION_CHECK = "AFTER_PERMISSION_CHECK"
|
||||
private const val PREFS_CONFIG_KEY = "LAST_CONF"
|
||||
private const val NOTIFICATION_ID = 1337
|
||||
|
|
@ -118,7 +121,7 @@ class AmneziaVpnService : VpnService() {
|
|||
|
||||
Action.CONNECT -> {
|
||||
val vpnConfig = msg.data.getString(VPN_CONFIG)
|
||||
saveConfigToPrefs(vpnConfig)
|
||||
Prefs.save(PREFS_CONFIG_KEY, vpnConfig)
|
||||
connect(vpnConfig)
|
||||
}
|
||||
|
||||
|
|
@ -135,6 +138,10 @@ class AmneziaVpnService : VpnService() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Action.SET_SAVE_LOGS -> {
|
||||
Log.saveLogs = msg.data.getBoolean(SAVE_LOGS)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -179,7 +186,7 @@ class AmneziaVpnService : VpnService() {
|
|||
*/
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
Log.v(TAG, "Create Amnezia VPN service")
|
||||
Log.d(TAG, "Create Amnezia VPN service")
|
||||
mainScope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
|
||||
connectionScope = CoroutineScope(SupervisorJob() + Dispatchers.IO + connectionExceptionHandler)
|
||||
clientMessenger = IpcMessenger(messengerName = "Client")
|
||||
|
|
@ -193,15 +200,15 @@ class AmneziaVpnService : VpnService() {
|
|||
else intent?.component?.packageName != packageName
|
||||
|
||||
if (isAlwaysOnCompat) {
|
||||
Log.v(TAG, "Start service via Always-on")
|
||||
connect(loadConfigFromPrefs())
|
||||
Log.d(TAG, "Start service via Always-on")
|
||||
connect(Prefs.load(PREFS_CONFIG_KEY))
|
||||
} else if (intent?.getBooleanExtra(AFTER_PERMISSION_CHECK, false) == true) {
|
||||
Log.v(TAG, "Start service after permission check")
|
||||
connect(loadConfigFromPrefs())
|
||||
Log.d(TAG, "Start service after permission check")
|
||||
connect(Prefs.load(PREFS_CONFIG_KEY))
|
||||
} else {
|
||||
Log.v(TAG, "Start service")
|
||||
Log.d(TAG, "Start service")
|
||||
val vpnConfig = intent?.getStringExtra(VPN_CONFIG)
|
||||
saveConfigToPrefs(vpnConfig)
|
||||
Prefs.save(PREFS_CONFIG_KEY, vpnConfig)
|
||||
connect(vpnConfig)
|
||||
}
|
||||
ServiceCompat.startForeground(this, NOTIFICATION_ID, notification, foregroundServiceTypeCompat)
|
||||
|
|
@ -237,7 +244,7 @@ class AmneziaVpnService : VpnService() {
|
|||
}
|
||||
|
||||
override fun onRevoke() {
|
||||
Log.v(TAG, "onRevoke")
|
||||
Log.d(TAG, "onRevoke")
|
||||
// Calls to onRevoke() method may not happen on the main thread of the process
|
||||
mainScope.launch {
|
||||
disconnect()
|
||||
|
|
@ -245,7 +252,7 @@ class AmneziaVpnService : VpnService() {
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
Log.v(TAG, "Destroy service")
|
||||
Log.d(TAG, "Destroy service")
|
||||
runBlocking {
|
||||
disconnect()
|
||||
disconnectionJob?.join()
|
||||
|
|
@ -256,7 +263,7 @@ class AmneziaVpnService : VpnService() {
|
|||
}
|
||||
|
||||
private fun stopService() {
|
||||
Log.v(TAG, "Stop service")
|
||||
Log.d(TAG, "Stop service")
|
||||
// the coroutine below will be canceled during the onDestroy call
|
||||
mainScope.launch {
|
||||
delay(STOP_SERVICE_TIMEOUT)
|
||||
|
|
@ -272,7 +279,7 @@ class AmneziaVpnService : VpnService() {
|
|||
private fun launchProtocolStateHandler() {
|
||||
mainScope.launch {
|
||||
protocolState.collect { protocolState ->
|
||||
Log.d(TAG, "Protocol state: $protocolState")
|
||||
Log.d(TAG, "Protocol state changed: $protocolState")
|
||||
when (protocolState) {
|
||||
CONNECTED -> {
|
||||
clientMessenger.send(ServiceEvent.CONNECTED)
|
||||
|
|
@ -305,7 +312,7 @@ class AmneziaVpnService : VpnService() {
|
|||
|
||||
@MainThread
|
||||
private fun launchSendingStatistics() {
|
||||
if (isServiceBound && isConnected) {
|
||||
/* if (isServiceBound && isConnected) {
|
||||
statisticsSendingJob = mainScope.launch {
|
||||
while (true) {
|
||||
clientMessenger.send {
|
||||
|
|
@ -316,7 +323,7 @@ class AmneziaVpnService : VpnService() {
|
|||
delay(STATISTICS_SENDING_TIMEOUT)
|
||||
}
|
||||
}
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
@MainThread
|
||||
|
|
@ -328,7 +335,7 @@ class AmneziaVpnService : VpnService() {
|
|||
private fun connect(vpnConfig: String?) {
|
||||
if (isConnected || protocolState.value == CONNECTING) return
|
||||
|
||||
Log.v(TAG, "Start VPN connection")
|
||||
Log.d(TAG, "Start VPN connection")
|
||||
|
||||
protocolState.value = CONNECTING
|
||||
|
||||
|
|
@ -357,7 +364,7 @@ class AmneziaVpnService : VpnService() {
|
|||
private fun disconnect() {
|
||||
if (isUnknown || isDisconnected || protocolState.value == DISCONNECTING) return
|
||||
|
||||
Log.v(TAG, "Stop VPN connection")
|
||||
Log.d(TAG, "Stop VPN connection")
|
||||
|
||||
protocolState.value = DISCONNECTING
|
||||
|
||||
|
|
@ -383,7 +390,7 @@ class AmneziaVpnService : VpnService() {
|
|||
private fun reconnect() {
|
||||
if (!isConnected) return
|
||||
|
||||
Log.v(TAG, "Reconnect VPN")
|
||||
Log.d(TAG, "Reconnect VPN")
|
||||
|
||||
protocolState.value = RECONNECTING
|
||||
|
||||
|
|
@ -439,10 +446,4 @@ class AmneziaVpnService : VpnService() {
|
|||
} else {
|
||||
true
|
||||
}
|
||||
|
||||
private fun loadConfigFromPrefs(): String? =
|
||||
Prefs.get(this).getString(PREFS_CONFIG_KEY, null)
|
||||
|
||||
private fun saveConfigToPrefs(config: String?) =
|
||||
Prefs.get(this).edit().putString(PREFS_CONFIG_KEY, config).apply()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,20 +29,20 @@ class ImportConfigActivity : ComponentActivity() {
|
|||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
Log.v(TAG, "Create Import Config Activity: $intent")
|
||||
Log.d(TAG, "Create Import Config Activity: $intent")
|
||||
intent?.let(::readConfig)
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
Log.v(TAG, "onNewIntent: $intent")
|
||||
Log.d(TAG, "onNewIntent: $intent")
|
||||
intent?.let(::readConfig)
|
||||
}
|
||||
|
||||
private fun readConfig(intent: Intent) {
|
||||
when (intent.action) {
|
||||
ACTION_SEND -> {
|
||||
Log.v(TAG, "Process SEND action, type: ${intent.type}")
|
||||
Log.d(TAG, "Process SEND action, type: ${intent.type}")
|
||||
when (intent.type) {
|
||||
"application/octet-stream" -> {
|
||||
intent.getUriCompat()?.let { uri ->
|
||||
|
|
@ -60,7 +60,7 @@ class ImportConfigActivity : ComponentActivity() {
|
|||
}
|
||||
|
||||
ACTION_VIEW -> {
|
||||
Log.v(TAG, "Process VIEW action, scheme: ${intent.scheme}")
|
||||
Log.d(TAG, "Process VIEW action, scheme: ${intent.scheme}")
|
||||
when (intent.scheme) {
|
||||
"file", "content" -> {
|
||||
intent.data?.let { uri ->
|
||||
|
|
@ -128,7 +128,7 @@ class ImportConfigActivity : ComponentActivity() {
|
|||
|
||||
private fun startMainActivity(config: String) {
|
||||
if (config.isNotBlank()) {
|
||||
Log.v(TAG, "startMainActivity")
|
||||
Log.d(TAG, "startMainActivity")
|
||||
Intent(applicationContext, AmneziaActivity::class.java).apply {
|
||||
action = ACTION_IMPORT_CONFIG
|
||||
addCategory(CATEGORY_DEFAULT)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ enum class Action : IpcMessage {
|
|||
REGISTER_CLIENT,
|
||||
CONNECT,
|
||||
DISCONNECT,
|
||||
REQUEST_STATUS
|
||||
REQUEST_STATUS,
|
||||
SET_SAVE_LOGS
|
||||
}
|
||||
|
||||
fun <T> T.packToMessage(): Message
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
package org.amnezia.vpn
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import androidx.security.crypto.EncryptedSharedPreferences
|
||||
import androidx.security.crypto.MasterKey
|
||||
import org.amnezia.vpn.util.Log
|
||||
|
||||
private const val TAG = "Prefs"
|
||||
private const val PREFS_FILE = "org.amnezia.vpn.prefs"
|
||||
private const val SECURE_PREFS_FILE = "$PREFS_FILE.secure"
|
||||
|
||||
object Prefs {
|
||||
fun get(context: Context, appContext: Context = context.applicationContext): SharedPreferences =
|
||||
try {
|
||||
EncryptedSharedPreferences(
|
||||
appContext,
|
||||
SECURE_PREFS_FILE,
|
||||
MasterKey(appContext)
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Getting Encryption Storage failed: ${e.message}, plaintext fallback")
|
||||
appContext.getSharedPreferences(PREFS_FILE, Context.MODE_PRIVATE)
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ class VpnRequestActivity : ComponentActivity() {
|
|||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
Log.v(TAG, "Start request activity")
|
||||
Log.d(TAG, "Start request activity")
|
||||
val requestIntent = VpnService.prepare(applicationContext)
|
||||
if (requestIntent != null) {
|
||||
if (getSystemService<KeyguardManager>()!!.isKeyguardLocked) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue