Fixed import from external applications
This commit is contained in:
parent
7e663b05d5
commit
9e461ef6e1
8 changed files with 256 additions and 154 deletions
140
client/android/src/org/amnezia/vpn/qt/ImportConfigActivity.kt
Normal file
140
client/android/src/org/amnezia/vpn/qt/ImportConfigActivity.kt
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
package org.amnezia.vpn.qt
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.ContentResolver
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.provider.MediaStore
|
||||
import android.widget.Toast
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
|
||||
import java.io.*
|
||||
|
||||
import org.amnezia.vpn.R
|
||||
|
||||
|
||||
const val INTENT_ACTION_IMPORT_CONFIG = "org.amnezia.vpn.qt.IMPORT_CONFIG"
|
||||
|
||||
class ImportConfigActivity : Activity() {
|
||||
|
||||
private val STORAGE_PERMISSION_CODE = 42
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_import_config)
|
||||
startReadConfig(intent)
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
startReadConfig(intent)
|
||||
}
|
||||
|
||||
private fun startMainActivity(config: String?) {
|
||||
|
||||
if (config == null || config.length == 0) {
|
||||
return
|
||||
}
|
||||
|
||||
val activityIntent = Intent(applicationContext, VPNActivity::class.java)
|
||||
activityIntent.action = INTENT_ACTION_IMPORT_CONFIG
|
||||
activityIntent.addCategory("android.intent.category.DEFAULT")
|
||||
activityIntent.putExtra("CONFIG", config)
|
||||
|
||||
startActivity(activityIntent)
|
||||
finish()
|
||||
}
|
||||
|
||||
private fun startReadConfig(intent: Intent?) {
|
||||
val newIntent = intent
|
||||
val newIntentAction: String = newIntent?.action ?: ""
|
||||
|
||||
if (newIntent != null && newIntentAction == Intent.ACTION_VIEW) {
|
||||
readConfig(newIntent, newIntentAction)
|
||||
}
|
||||
}
|
||||
|
||||
private fun readConfig(newIntent: Intent, newIntentAction: String) {
|
||||
if (isReadStorageAllowed()) {
|
||||
val configString = processIntent(newIntent, newIntentAction)
|
||||
startMainActivity(configString)
|
||||
} else {
|
||||
requestStoragePermission()
|
||||
}
|
||||
}
|
||||
|
||||
private fun requestStoragePermission() {
|
||||
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), STORAGE_PERMISSION_CODE)
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String?>, grantResults: IntArray) {
|
||||
if (requestCode == STORAGE_PERMISSION_CODE) {
|
||||
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
val configString = processIntent(intent, intent.action!!)
|
||||
|
||||
if (configString != null) {
|
||||
startMainActivity(configString)
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(this, "Oops you just denied the permission", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun processIntent(intent: Intent, action: String): String? {
|
||||
val scheme = intent.scheme
|
||||
|
||||
if (scheme == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (action.compareTo(Intent.ACTION_VIEW) == 0) {
|
||||
val resolver = contentResolver
|
||||
|
||||
if (scheme.compareTo(ContentResolver.SCHEME_CONTENT) == 0) {
|
||||
val uri = intent.data
|
||||
val name: String? = getContentName(resolver, uri)
|
||||
|
||||
println("Content intent detected: " + action + " : " + intent.dataString + " : " + intent.type + " : " + name)
|
||||
|
||||
val input = resolver.openInputStream(uri!!)
|
||||
|
||||
return input?.bufferedReader()?.use(BufferedReader::readText)
|
||||
} else if (scheme.compareTo(ContentResolver.SCHEME_FILE) == 0) {
|
||||
val uri = intent.data
|
||||
val name = uri!!.lastPathSegment
|
||||
|
||||
println("File intent detected: " + action + " : " + intent.dataString + " : " + intent.type + " : " + name)
|
||||
|
||||
val input = resolver.openInputStream(uri)
|
||||
|
||||
return input?.bufferedReader()?.use(BufferedReader::readText)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun isReadStorageAllowed(): Boolean {
|
||||
val permissionStatus = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
return permissionStatus == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
|
||||
private fun getContentName(resolver: ContentResolver?, uri: Uri?): String? {
|
||||
val cursor = resolver!!.query(uri!!, null, null, null, null)
|
||||
|
||||
cursor.use {
|
||||
cursor!!.moveToFirst()
|
||||
val nameIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)
|
||||
return if (nameIndex >= 0) {
|
||||
return cursor.getString(nameIndex)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -34,15 +34,23 @@ class VPNActivity : org.qtproject.qt.android.bindings.QtActivity() {
|
|||
private var configString: String? = null
|
||||
private var vpnServiceBinder: IBinder? = null
|
||||
private var isBound = false
|
||||
set(value) {
|
||||
field = value
|
||||
|
||||
if (value && configString != null) {
|
||||
sendImportConfigCommand()
|
||||
}
|
||||
}
|
||||
|
||||
private val TAG = "VPNActivity"
|
||||
private val STORAGE_PERMISSION_CODE = 42
|
||||
|
||||
private val CAMERA_ACTION_CODE = 101
|
||||
private val CREATE_FILE_ACTION_CODE = 102
|
||||
|
||||
private var tmpFileContentToSave: String = ""
|
||||
|
||||
private val delayedCommands: ArrayList<Pair<Int, String>> = ArrayList()
|
||||
|
||||
companion object {
|
||||
private lateinit var instance: VPNActivity
|
||||
|
||||
|
|
@ -72,16 +80,16 @@ class VPNActivity : org.qtproject.qt.android.bindings.QtActivity() {
|
|||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
val newIntent = intent
|
||||
val newIntentAction = newIntent.action
|
||||
|
||||
if (newIntent != null && newIntentAction != null) {
|
||||
configString = processIntent(newIntent, newIntentAction)
|
||||
}
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
instance = this
|
||||
|
||||
val newIntent = intent
|
||||
val newIntentAction: String? = newIntent.action
|
||||
|
||||
if (newIntent != null && newIntentAction != null && newIntentAction == "org.amnezia.vpn.qt.IMPORT_CONFIG") {
|
||||
configString = newIntent.getStringExtra("CONFIG")
|
||||
}
|
||||
}
|
||||
|
||||
private fun startQrCodeActivity() {
|
||||
|
|
@ -123,9 +131,22 @@ class VPNActivity : org.qtproject.qt.android.bindings.QtActivity() {
|
|||
private fun dispatchParcel(actionCode: Int, body: String) {
|
||||
if (!isBound) {
|
||||
Log.d(TAG, "dispatchParcel: not bound")
|
||||
delayedCommands.add(Pair(actionCode, body))
|
||||
return
|
||||
}
|
||||
|
||||
if (delayedCommands.size > 0) {
|
||||
for (command in delayedCommands) {
|
||||
processCommand(command.first, command.second)
|
||||
}
|
||||
|
||||
delayedCommands.clear()
|
||||
}
|
||||
|
||||
processCommand(actionCode, body)
|
||||
}
|
||||
|
||||
private fun processCommand(actionCode: Int, body: String) {
|
||||
val out: Parcel = Parcel.obtain()
|
||||
out.writeByteArray(body.toByteArray())
|
||||
|
||||
|
|
@ -141,19 +162,15 @@ class VPNActivity : org.qtproject.qt.android.bindings.QtActivity() {
|
|||
}
|
||||
|
||||
override fun onNewIntent(newIntent: Intent) {
|
||||
intent = newIntent
|
||||
super.onNewIntent(intent)
|
||||
|
||||
setIntent(newIntent)
|
||||
|
||||
val newIntentAction = newIntent.action
|
||||
|
||||
if (newIntent != null && newIntentAction != null && newIntentAction != Intent.ACTION_MAIN) {
|
||||
if (isReadStorageAllowed()) {
|
||||
configString = processIntent(newIntent, newIntentAction)
|
||||
} else {
|
||||
requestStoragePermission()
|
||||
}
|
||||
}
|
||||
|
||||
super.onNewIntent(intent)
|
||||
if (newIntent != null && newIntentAction != null && newIntentAction == INTENT_ACTION_IMPORT_CONFIG) {
|
||||
configString = newIntent.getStringExtra("CONFIG")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
|
@ -164,84 +181,6 @@ class VPNActivity : org.qtproject.qt.android.bindings.QtActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun isReadStorageAllowed(): Boolean {
|
||||
val permissionStatus = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
return permissionStatus == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
|
||||
private fun requestStoragePermission() {
|
||||
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), STORAGE_PERMISSION_CODE)
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String?>, grantResults: IntArray) {
|
||||
if (requestCode == STORAGE_PERMISSION_CODE) {
|
||||
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
Log.d(TAG, "Storage read permission granted")
|
||||
|
||||
if (configString == null) {
|
||||
configString = processIntent(intent, intent.action!!)
|
||||
}
|
||||
|
||||
if (configString != null) {
|
||||
Log.d(TAG, "not empty")
|
||||
sendImportConfigCommand()
|
||||
} else {
|
||||
Log.d(TAG, "empty")
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(this, "Oops you just denied the permission", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun processIntent(intent: Intent, action: String): String? {
|
||||
val scheme = intent.scheme
|
||||
|
||||
if (scheme == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (action.compareTo(Intent.ACTION_VIEW) == 0) {
|
||||
val resolver = contentResolver
|
||||
|
||||
if (scheme.compareTo(ContentResolver.SCHEME_CONTENT) == 0) {
|
||||
val uri = intent.data
|
||||
val name: String? = getContentName(resolver, uri)
|
||||
|
||||
Log.d(TAG, "Content intent detected: " + action + " : " + intent.dataString + " : " + intent.type + " : " + name)
|
||||
|
||||
val input = resolver.openInputStream(uri!!)
|
||||
|
||||
return input?.bufferedReader()?.use(BufferedReader::readText)
|
||||
} else if (scheme.compareTo(ContentResolver.SCHEME_FILE) == 0) {
|
||||
val uri = intent.data
|
||||
val name = uri!!.lastPathSegment
|
||||
|
||||
Log.d(TAG, "File intent detected: " + action + " : " + intent.dataString + " : " + intent.type + " : " + name)
|
||||
|
||||
val input = resolver.openInputStream(uri)
|
||||
|
||||
return input?.bufferedReader()?.use(BufferedReader::readText)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getContentName(resolver: ContentResolver?, uri: Uri?): String? {
|
||||
val cursor = resolver!!.query(uri!!, null, null, null, null)
|
||||
|
||||
cursor.use {
|
||||
cursor!!.moveToFirst()
|
||||
val nameIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)
|
||||
return if (nameIndex >= 0) {
|
||||
return cursor.getString(nameIndex)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendImportConfigCommand() {
|
||||
if (configString != null) {
|
||||
val msg: Parcel = Parcel.obtain()
|
||||
|
|
@ -257,7 +196,7 @@ class VPNActivity : org.qtproject.qt.android.bindings.QtActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private var connection: ServiceConnection = object : ServiceConnection {
|
||||
private fun createConnection() = object : ServiceConnection {
|
||||
override fun onServiceConnected(className: ComponentName, binder: IBinder) {
|
||||
vpnServiceBinder = binder
|
||||
|
||||
|
|
@ -283,6 +222,8 @@ class VPNActivity : org.qtproject.qt.android.bindings.QtActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private var connection: ServiceConnection = createConnection()
|
||||
|
||||
private fun registerBinder(): Boolean {
|
||||
val binder = VPNClientBinder()
|
||||
val out: Parcel = Parcel.obtain()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue