mirror of
https://github.com/yggdrasil-network/yggdrasil-android.git
synced 2025-04-28 22:25:09 +03:00
Changes for updating to Yggdrasil 0.5. (#49)
This commit is contained in:
parent
9df80c0612
commit
f4e1a75cfc
16 changed files with 189 additions and 78 deletions
|
@ -32,14 +32,12 @@ object ConfigurationProxy {
|
|||
val newJson = JSONObject(String(Mobile.generateConfigJSON()))
|
||||
updateJSON { json ->
|
||||
json.put("PrivateKey", newJson.getString("PrivateKey"))
|
||||
json.put("PublicKey", newJson.getString("PublicKey"))
|
||||
}
|
||||
}
|
||||
|
||||
fun setKeys(privateKey: String, publicKey: String) {
|
||||
fun setKeys(privateKey: String) {
|
||||
updateJSON { json ->
|
||||
json.put("PrivateKey", privateKey)
|
||||
json.put("PublicKey", publicKey)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,7 +60,8 @@ object ConfigurationProxy {
|
|||
{
|
||||
"Regex": ".*",
|
||||
"Beacon": true,
|
||||
"Listen": true
|
||||
"Listen": true,
|
||||
"Password": ""
|
||||
}
|
||||
""".trimIndent()))
|
||||
json.put("MulticastInterfaces", ar)
|
||||
|
@ -94,4 +93,12 @@ object ConfigurationProxy {
|
|||
(json.getJSONArray("MulticastInterfaces").get(0) as JSONObject).put("Beacon", value)
|
||||
}
|
||||
}
|
||||
|
||||
var multicastPassword: String
|
||||
get() = (json.getJSONArray("MulticastInterfaces").get(0) as JSONObject).getString("Password")
|
||||
set(value) {
|
||||
updateJSON { json ->
|
||||
(json.getJSONArray("MulticastInterfaces").get(0) as JSONObject).put("Password", value)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -47,8 +47,10 @@ class GlobalApplication: Application(), YggStateReceiver.StateReceiver {
|
|||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
override fun onStateChange(state: State) {
|
||||
if (state != currentState) {
|
||||
val componentName = ComponentName(this, YggTileService::class.java)
|
||||
TileService.requestListeningState(this, componentName)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
val componentName = ComponentName(this, YggTileService::class.java)
|
||||
TileService.requestListeningState(this, componentName)
|
||||
}
|
||||
|
||||
if (state != State.Disabled) {
|
||||
val notification = createServiceNotification(this, state)
|
||||
|
@ -68,7 +70,11 @@ fun createServiceNotification(context: Context, state: State): Notification {
|
|||
val intent = Intent(context, MainActivity::class.java).apply {
|
||||
this.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
}
|
||||
val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
var flags = PendingIntent.FLAG_UPDATE_CURRENT
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
flags = PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
}
|
||||
val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, intent, flags)
|
||||
|
||||
val text = when (state) {
|
||||
State.Disabled -> context.getText(R.string.tile_disabled)
|
||||
|
@ -91,7 +97,11 @@ fun createPermissionMissingNotification(context: Context): Notification {
|
|||
val intent = Intent(context, MainActivity::class.java).apply {
|
||||
this.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
}
|
||||
val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
var flags = PendingIntent.FLAG_UPDATE_CURRENT
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
flags = PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
}
|
||||
val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, intent, flags)
|
||||
|
||||
return NotificationCompat.Builder(context, MAIN_CHANNEL_ID)
|
||||
.setShowWhen(false)
|
||||
|
|
|
@ -24,7 +24,7 @@ class MainActivity : AppCompatActivity() {
|
|||
private lateinit var enabledLabel: TextView
|
||||
private lateinit var ipAddressLabel: TextView
|
||||
private lateinit var subnetLabel: TextView
|
||||
private lateinit var coordinatesLabel: TextView
|
||||
private lateinit var treeLengthLabel: TextView
|
||||
private lateinit var peersLabel: TextView
|
||||
private lateinit var peersRow: LinearLayoutCompat
|
||||
private lateinit var dnsLabel: TextView
|
||||
|
@ -53,7 +53,7 @@ class MainActivity : AppCompatActivity() {
|
|||
enabledLabel = findViewById(R.id.yggdrasilStatusLabel)
|
||||
ipAddressLabel = findViewById(R.id.ipAddressValue)
|
||||
subnetLabel = findViewById(R.id.subnetValue)
|
||||
coordinatesLabel = findViewById(R.id.coordinatesValue)
|
||||
treeLengthLabel = findViewById(R.id.treeLengthValue)
|
||||
peersLabel = findViewById(R.id.peersValue)
|
||||
peersRow = findViewById(R.id.peersTableRow)
|
||||
dnsLabel = findViewById(R.id.dnsValue)
|
||||
|
@ -155,11 +155,11 @@ class MainActivity : AppCompatActivity() {
|
|||
"state" -> {
|
||||
enabledLabel.text = if (intent.getBooleanExtra("started", false)) {
|
||||
var count = 0
|
||||
if (intent.hasExtra("dht")) {
|
||||
val dht = intent.getStringExtra("dht")
|
||||
if (dht != null && dht != "null") {
|
||||
val dhtState = JSONArray(dht)
|
||||
count = dhtState.length()
|
||||
if (intent.hasExtra("tree")) {
|
||||
val tree = intent.getStringExtra("tree")
|
||||
if (tree != null && tree != "null") {
|
||||
val treeState = JSONArray(tree)
|
||||
count = treeState.length()
|
||||
}
|
||||
}
|
||||
if (count == 0) {
|
||||
|
@ -175,7 +175,7 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
ipAddressLabel.text = intent.getStringExtra("ip") ?: "N/A"
|
||||
subnetLabel.text = intent.getStringExtra("subnet") ?: "N/A"
|
||||
coordinatesLabel.text = intent.getStringExtra("coords") ?: "[]"
|
||||
treeLengthLabel.text = intent.getStringExtra("coords") ?: "0"
|
||||
if (intent.hasExtra("peers")) {
|
||||
val peerState = JSONArray(intent.getStringExtra("peers") ?: "[]")
|
||||
peersLabel.text = when (val count = peerState.length()) {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package eu.neilalexander.yggdrasil
|
||||
|
||||
import android.content.*
|
||||
import android.content.Intent
|
||||
import android.net.VpnService
|
||||
import android.net.wifi.WifiManager
|
||||
import android.os.Build
|
||||
import android.os.ParcelFileDescriptor
|
||||
import android.system.OsConstants
|
||||
|
@ -42,6 +43,7 @@ open class PacketTunnelProvider: VpnService() {
|
|||
private var parcel: ParcelFileDescriptor? = null
|
||||
private var readerStream: FileInputStream? = null
|
||||
private var writerStream: FileOutputStream? = null
|
||||
private var multicastLock: WifiManager.MulticastLock? = null
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
@ -101,6 +103,13 @@ open class PacketTunnelProvider: VpnService() {
|
|||
val notification = createServiceNotification(this, State.Enabled)
|
||||
startForeground(SERVICE_NOTIFICATION_ID, notification)
|
||||
|
||||
// Acquire multicast lock
|
||||
val wifi = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
|
||||
multicastLock = wifi.createMulticastLock("Yggdrasil").apply {
|
||||
setReferenceCounted(false)
|
||||
acquire()
|
||||
}
|
||||
|
||||
Log.d(TAG, config.getJSON().toString())
|
||||
yggdrasil.startJSON(config.getJSONByteArray())
|
||||
|
||||
|
@ -163,16 +172,7 @@ open class PacketTunnelProvider: VpnService() {
|
|||
updater()
|
||||
}
|
||||
|
||||
var intent = Intent(STATE_INTENT)
|
||||
intent.putExtra("type", "state")
|
||||
intent.putExtra("started", true)
|
||||
intent.putExtra("ip", yggdrasil.addressString)
|
||||
intent.putExtra("subnet", yggdrasil.subnetString)
|
||||
intent.putExtra("coords", yggdrasil.coordsString)
|
||||
intent.putExtra("peers", yggdrasil.peersJSON)
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
|
||||
|
||||
intent = Intent(YGG_STATE_INTENT)
|
||||
var intent = Intent(YGG_STATE_INTENT)
|
||||
intent.putExtra("state", STATE_ENABLED)
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
|
||||
}
|
||||
|
@ -221,6 +221,7 @@ open class PacketTunnelProvider: VpnService() {
|
|||
|
||||
stopForeground(true)
|
||||
stopSelf()
|
||||
multicastLock?.release()
|
||||
}
|
||||
|
||||
private fun connect() {
|
||||
|
@ -231,27 +232,37 @@ open class PacketTunnelProvider: VpnService() {
|
|||
}
|
||||
|
||||
private fun updater() {
|
||||
Thread.sleep(500)
|
||||
var lastStateUpdate = System.currentTimeMillis()
|
||||
updates@ while (started.get()) {
|
||||
val treeJSON = yggdrasil.treeJSON
|
||||
var treeLength = 0
|
||||
if (treeJSON != null && treeJSON != "null") {
|
||||
val treeState = JSONArray(treeJSON)
|
||||
treeLength = treeState.length()
|
||||
}
|
||||
if ((application as GlobalApplication).needUiUpdates()) {
|
||||
val intent = Intent(STATE_INTENT)
|
||||
intent.putExtra("type", "state")
|
||||
intent.putExtra("started", true)
|
||||
intent.putExtra("ip", yggdrasil.addressString)
|
||||
intent.putExtra("subnet", yggdrasil.subnetString)
|
||||
intent.putExtra("coords", yggdrasil.coordsString)
|
||||
intent.putExtra("pubkey", yggdrasil.publicKeyString)
|
||||
intent.putExtra("coords", "$treeLength")
|
||||
intent.putExtra("peers", yggdrasil.peersJSON)
|
||||
intent.putExtra("dht", yggdrasil.dhtjson)
|
||||
intent.putExtra("tree", treeJSON)
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
|
||||
}
|
||||
val curTime = System.currentTimeMillis()
|
||||
if (lastStateUpdate + 10000 < curTime) {
|
||||
val intent = Intent(YGG_STATE_INTENT)
|
||||
var state = STATE_ENABLED
|
||||
val dht = yggdrasil.dhtjson
|
||||
if (dht != null && dht != "null") {
|
||||
val dhtState = JSONArray(dht)
|
||||
val count = dhtState.length()
|
||||
if (yggdrasil.routingEntries > 0) {
|
||||
state = STATE_CONNECTED
|
||||
}
|
||||
if (treeJSON != null && treeJSON != "null") {
|
||||
val treeState = JSONArray(treeJSON)
|
||||
val count = treeState.length()
|
||||
if (count > 1)
|
||||
state = STATE_CONNECTED
|
||||
}
|
||||
|
|
|
@ -7,10 +7,13 @@ import android.content.Intent
|
|||
import android.content.IntentFilter
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.ContextThemeWrapper
|
||||
import android.view.KeyEvent
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.*
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
import org.json.JSONArray
|
||||
|
@ -27,6 +30,7 @@ class PeersActivity : AppCompatActivity() {
|
|||
private lateinit var configuredTableLabel: TextView
|
||||
private lateinit var multicastListenSwitch: Switch
|
||||
private lateinit var multicastBeaconSwitch: Switch
|
||||
private lateinit var passwordEdit: EditText
|
||||
private lateinit var addPeerButton: ImageButton
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
@ -62,6 +66,30 @@ class PeersActivity : AppCompatActivity() {
|
|||
multicastListenPanel.setOnClickListener {
|
||||
multicastListenSwitch.toggle()
|
||||
}
|
||||
passwordEdit = findViewById(R.id.passwordEdit)
|
||||
passwordEdit.setText(config.multicastPassword)
|
||||
|
||||
passwordEdit.doOnTextChanged { text, _, _, _ ->
|
||||
config.multicastPassword = text.toString()
|
||||
}
|
||||
|
||||
passwordEdit.setOnKeyListener { _, keyCode, _ ->
|
||||
(keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER)
|
||||
}
|
||||
|
||||
findViewById<View>(R.id.passwordTableRow).setOnKeyListener { _, keyCode, event ->
|
||||
Log.i("Key", keyCode.toString())
|
||||
if (event.action == KeyEvent.ACTION_DOWN) {
|
||||
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER) {
|
||||
passwordEdit.requestFocus()
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
addPeerButton = findViewById(R.id.addPeerButton)
|
||||
addPeerButton.setOnClickListener {
|
||||
|
@ -156,7 +184,7 @@ class PeersActivity : AppCompatActivity() {
|
|||
val view = inflater.inflate(R.layout.peers_connected, null)
|
||||
val ip = peer.getString("IP")
|
||||
view.findViewById<TextView>(R.id.addressLabel).text = ip
|
||||
view.findViewById<TextView>(R.id.detailsLabel).text = peer.getString("Remote")
|
||||
view.findViewById<TextView>(R.id.detailsLabel).text = peer.getString("URI")
|
||||
connectedTableLayout.addView(view)
|
||||
}
|
||||
}
|
||||
|
@ -168,7 +196,9 @@ class PeersActivity : AppCompatActivity() {
|
|||
when (intent.getStringExtra("type")) {
|
||||
"state" -> {
|
||||
if (intent.hasExtra("peers")) {
|
||||
val peersArray = JSONArray(intent.getStringExtra("peers") ?: "[]")
|
||||
val peers1 = intent.getStringExtra("peers")
|
||||
//Log.i("PeersActivity", "Peers json: $peers1")
|
||||
val peersArray = JSONArray(peers1 ?: "[]")
|
||||
val array = Array(peersArray.length()) { i ->
|
||||
peersArray.getJSONObject(i)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
package eu.neilalexander.yggdrasil
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
|
@ -13,6 +17,7 @@ import android.view.View
|
|||
import android.widget.*
|
||||
import androidx.appcompat.widget.LinearLayoutCompat
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import org.json.JSONObject
|
||||
|
||||
class SettingsActivity : AppCompatActivity() {
|
||||
|
@ -87,11 +92,10 @@ class SettingsActivity : AppCompatActivity() {
|
|||
val view = inflater.inflate(R.layout.dialog_set_keys, null)
|
||||
val builder: AlertDialog.Builder = AlertDialog.Builder(ContextThemeWrapper(this, R.style.Theme_MaterialComponents_DayNight_Dialog))
|
||||
val privateKey = view.findViewById<EditText>(R.id.private_key)
|
||||
val publicKey = view.findViewById<EditText>(R.id.public_key)
|
||||
builder.setTitle(getString(R.string.set_keys))
|
||||
builder.setView(view)
|
||||
builder.setPositiveButton(getString(R.string.save)) { dialog, _ ->
|
||||
config.setKeys(privateKey.text.toString(), publicKey.text.toString())
|
||||
config.setKeys(privateKey.text.toString())
|
||||
updateView()
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
@ -113,13 +117,40 @@ class SettingsActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
private fun updateView() {
|
||||
val nodeinfo = config.getJSON().optJSONObject("NodeInfo")
|
||||
val json = config.getJSON()
|
||||
val nodeinfo = json.optJSONObject("NodeInfo")
|
||||
if (nodeinfo != null) {
|
||||
deviceNameEntry.setText(nodeinfo.getString("name"), TextView.BufferType.EDITABLE)
|
||||
} else {
|
||||
deviceNameEntry.setText("", TextView.BufferType.EDITABLE)
|
||||
}
|
||||
|
||||
publicKeyLabel.text = config.getJSON().getString("PublicKey")
|
||||
publicKeyLabel.text = json.optString("PublicKey")
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(
|
||||
receiver, IntentFilter(PacketTunnelProvider.STATE_INTENT)
|
||||
)
|
||||
(application as GlobalApplication).subscribe()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
(application as GlobalApplication).unsubscribe()
|
||||
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver)
|
||||
}
|
||||
|
||||
// To be able to get public key from running Yggdrasil we use this receiver, as we don't have this field in config
|
||||
private val receiver: BroadcastReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent) {
|
||||
if (intent.hasExtra("pubkey")) {
|
||||
val tree = intent.getStringExtra("pubkey")
|
||||
if (tree != null && tree != "null") {
|
||||
publicKeyLabel.text = intent.getStringExtra("pubkey")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue