Changes for updating to Yggdrasil 0.5. (#49)

This commit is contained in:
Revertron 2023-10-28 23:31:32 +02:00 committed by GitHub
parent 9df80c0612
commit f4e1a75cfc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 189 additions and 78 deletions

View file

@ -4,15 +4,14 @@ plugins {
} }
android { android {
compileSdkVersion 29 compileSdkVersion 33
buildToolsVersion "30.0.3"
defaultConfig { defaultConfig {
applicationId "eu.neilalexander.yggdrasil" applicationId "eu.neilalexander.yggdrasil"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 29 targetSdkVersion 33
versionCode 13 versionCode 14
versionName "0.1-013" versionName "0.1-014"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
@ -51,12 +50,12 @@ android {
dependencies { dependencies {
implementation fileTree(include: ['*.aar'], dir: 'libs') implementation fileTree(include: ['*.aar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.5.0' implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.0' implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.3.0' implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.preference:preference-ktx:1.1.0' implementation 'androidx.preference:preference-ktx:1.2.1'
testImplementation 'junit:junit:4.+' testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
} }

View file

@ -5,6 +5,7 @@
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application <application
@ -23,8 +24,8 @@
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".SettingsActivity" android:parentActivityName=".MainActivity" /> <activity android:name=".SettingsActivity" android:parentActivityName=".MainActivity" android:exported="false" />
<activity android:name=".PeersActivity" android:parentActivityName=".MainActivity" /> <activity android:name=".PeersActivity" android:parentActivityName=".MainActivity" android:exported="false" />
<activity android:name=".DnsActivity" android:exported="false" /> <activity android:name=".DnsActivity" android:exported="false" />
<activity android:name=".TileServiceActivity" android:theme="@android:style/Theme.NoDisplay" <activity android:name=".TileServiceActivity" android:theme="@android:style/Theme.NoDisplay"
android:allowTaskReparenting="true" android:allowTaskReparenting="true"

View file

@ -32,14 +32,12 @@ object ConfigurationProxy {
val newJson = JSONObject(String(Mobile.generateConfigJSON())) val newJson = JSONObject(String(Mobile.generateConfigJSON()))
updateJSON { json -> updateJSON { json ->
json.put("PrivateKey", newJson.getString("PrivateKey")) json.put("PrivateKey", newJson.getString("PrivateKey"))
json.put("PublicKey", newJson.getString("PublicKey"))
} }
} }
fun setKeys(privateKey: String, publicKey: String) { fun setKeys(privateKey: String) {
updateJSON { json -> updateJSON { json ->
json.put("PrivateKey", privateKey) json.put("PrivateKey", privateKey)
json.put("PublicKey", publicKey)
} }
} }
@ -62,7 +60,8 @@ object ConfigurationProxy {
{ {
"Regex": ".*", "Regex": ".*",
"Beacon": true, "Beacon": true,
"Listen": true "Listen": true,
"Password": ""
} }
""".trimIndent())) """.trimIndent()))
json.put("MulticastInterfaces", ar) json.put("MulticastInterfaces", ar)
@ -94,4 +93,12 @@ object ConfigurationProxy {
(json.getJSONArray("MulticastInterfaces").get(0) as JSONObject).put("Beacon", value) (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)
}
}
} }

View file

@ -47,8 +47,10 @@ class GlobalApplication: Application(), YggStateReceiver.StateReceiver {
@RequiresApi(Build.VERSION_CODES.N) @RequiresApi(Build.VERSION_CODES.N)
override fun onStateChange(state: State) { override fun onStateChange(state: State) {
if (state != currentState) { if (state != currentState) {
val componentName = ComponentName(this, YggTileService::class.java) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
TileService.requestListeningState(this, componentName) val componentName = ComponentName(this, YggTileService::class.java)
TileService.requestListeningState(this, componentName)
}
if (state != State.Disabled) { if (state != State.Disabled) {
val notification = createServiceNotification(this, state) val notification = createServiceNotification(this, state)
@ -68,7 +70,11 @@ fun createServiceNotification(context: Context, state: State): Notification {
val intent = Intent(context, MainActivity::class.java).apply { val intent = Intent(context, MainActivity::class.java).apply {
this.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK 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) { val text = when (state) {
State.Disabled -> context.getText(R.string.tile_disabled) 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 { val intent = Intent(context, MainActivity::class.java).apply {
this.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK 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) return NotificationCompat.Builder(context, MAIN_CHANNEL_ID)
.setShowWhen(false) .setShowWhen(false)

View file

@ -24,7 +24,7 @@ class MainActivity : AppCompatActivity() {
private lateinit var enabledLabel: TextView private lateinit var enabledLabel: TextView
private lateinit var ipAddressLabel: TextView private lateinit var ipAddressLabel: TextView
private lateinit var subnetLabel: TextView private lateinit var subnetLabel: TextView
private lateinit var coordinatesLabel: TextView private lateinit var treeLengthLabel: TextView
private lateinit var peersLabel: TextView private lateinit var peersLabel: TextView
private lateinit var peersRow: LinearLayoutCompat private lateinit var peersRow: LinearLayoutCompat
private lateinit var dnsLabel: TextView private lateinit var dnsLabel: TextView
@ -53,7 +53,7 @@ class MainActivity : AppCompatActivity() {
enabledLabel = findViewById(R.id.yggdrasilStatusLabel) enabledLabel = findViewById(R.id.yggdrasilStatusLabel)
ipAddressLabel = findViewById(R.id.ipAddressValue) ipAddressLabel = findViewById(R.id.ipAddressValue)
subnetLabel = findViewById(R.id.subnetValue) subnetLabel = findViewById(R.id.subnetValue)
coordinatesLabel = findViewById(R.id.coordinatesValue) treeLengthLabel = findViewById(R.id.treeLengthValue)
peersLabel = findViewById(R.id.peersValue) peersLabel = findViewById(R.id.peersValue)
peersRow = findViewById(R.id.peersTableRow) peersRow = findViewById(R.id.peersTableRow)
dnsLabel = findViewById(R.id.dnsValue) dnsLabel = findViewById(R.id.dnsValue)
@ -155,11 +155,11 @@ class MainActivity : AppCompatActivity() {
"state" -> { "state" -> {
enabledLabel.text = if (intent.getBooleanExtra("started", false)) { enabledLabel.text = if (intent.getBooleanExtra("started", false)) {
var count = 0 var count = 0
if (intent.hasExtra("dht")) { if (intent.hasExtra("tree")) {
val dht = intent.getStringExtra("dht") val tree = intent.getStringExtra("tree")
if (dht != null && dht != "null") { if (tree != null && tree != "null") {
val dhtState = JSONArray(dht) val treeState = JSONArray(tree)
count = dhtState.length() count = treeState.length()
} }
} }
if (count == 0) { if (count == 0) {
@ -175,7 +175,7 @@ class MainActivity : AppCompatActivity() {
} }
ipAddressLabel.text = intent.getStringExtra("ip") ?: "N/A" ipAddressLabel.text = intent.getStringExtra("ip") ?: "N/A"
subnetLabel.text = intent.getStringExtra("subnet") ?: "N/A" subnetLabel.text = intent.getStringExtra("subnet") ?: "N/A"
coordinatesLabel.text = intent.getStringExtra("coords") ?: "[]" treeLengthLabel.text = intent.getStringExtra("coords") ?: "0"
if (intent.hasExtra("peers")) { if (intent.hasExtra("peers")) {
val peerState = JSONArray(intent.getStringExtra("peers") ?: "[]") val peerState = JSONArray(intent.getStringExtra("peers") ?: "[]")
peersLabel.text = when (val count = peerState.length()) { peersLabel.text = when (val count = peerState.length()) {

View file

@ -1,7 +1,8 @@
package eu.neilalexander.yggdrasil package eu.neilalexander.yggdrasil
import android.content.* import android.content.Intent
import android.net.VpnService import android.net.VpnService
import android.net.wifi.WifiManager
import android.os.Build import android.os.Build
import android.os.ParcelFileDescriptor import android.os.ParcelFileDescriptor
import android.system.OsConstants import android.system.OsConstants
@ -42,6 +43,7 @@ open class PacketTunnelProvider: VpnService() {
private var parcel: ParcelFileDescriptor? = null private var parcel: ParcelFileDescriptor? = null
private var readerStream: FileInputStream? = null private var readerStream: FileInputStream? = null
private var writerStream: FileOutputStream? = null private var writerStream: FileOutputStream? = null
private var multicastLock: WifiManager.MulticastLock? = null
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
@ -101,6 +103,13 @@ open class PacketTunnelProvider: VpnService() {
val notification = createServiceNotification(this, State.Enabled) val notification = createServiceNotification(this, State.Enabled)
startForeground(SERVICE_NOTIFICATION_ID, notification) 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()) Log.d(TAG, config.getJSON().toString())
yggdrasil.startJSON(config.getJSONByteArray()) yggdrasil.startJSON(config.getJSONByteArray())
@ -163,16 +172,7 @@ open class PacketTunnelProvider: VpnService() {
updater() updater()
} }
var intent = Intent(STATE_INTENT) var intent = Intent(YGG_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)
intent.putExtra("state", STATE_ENABLED) intent.putExtra("state", STATE_ENABLED)
LocalBroadcastManager.getInstance(this).sendBroadcast(intent) LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
} }
@ -221,6 +221,7 @@ open class PacketTunnelProvider: VpnService() {
stopForeground(true) stopForeground(true)
stopSelf() stopSelf()
multicastLock?.release()
} }
private fun connect() { private fun connect() {
@ -231,27 +232,37 @@ open class PacketTunnelProvider: VpnService() {
} }
private fun updater() { private fun updater() {
Thread.sleep(500)
var lastStateUpdate = System.currentTimeMillis() var lastStateUpdate = System.currentTimeMillis()
updates@ while (started.get()) { 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()) { if ((application as GlobalApplication).needUiUpdates()) {
val intent = Intent(STATE_INTENT) val intent = Intent(STATE_INTENT)
intent.putExtra("type", "state") intent.putExtra("type", "state")
intent.putExtra("started", true) intent.putExtra("started", true)
intent.putExtra("ip", yggdrasil.addressString) intent.putExtra("ip", yggdrasil.addressString)
intent.putExtra("subnet", yggdrasil.subnetString) 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("peers", yggdrasil.peersJSON)
intent.putExtra("dht", yggdrasil.dhtjson) intent.putExtra("tree", treeJSON)
LocalBroadcastManager.getInstance(this).sendBroadcast(intent) LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
} }
val curTime = System.currentTimeMillis() val curTime = System.currentTimeMillis()
if (lastStateUpdate + 10000 < curTime) { if (lastStateUpdate + 10000 < curTime) {
val intent = Intent(YGG_STATE_INTENT) val intent = Intent(YGG_STATE_INTENT)
var state = STATE_ENABLED var state = STATE_ENABLED
val dht = yggdrasil.dhtjson if (yggdrasil.routingEntries > 0) {
if (dht != null && dht != "null") { state = STATE_CONNECTED
val dhtState = JSONArray(dht) }
val count = dhtState.length() if (treeJSON != null && treeJSON != "null") {
val treeState = JSONArray(treeJSON)
val count = treeState.length()
if (count > 1) if (count > 1)
state = STATE_CONNECTED state = STATE_CONNECTED
} }

View file

@ -7,10 +7,13 @@ import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.ContextThemeWrapper import android.view.ContextThemeWrapper
import android.view.KeyEvent
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.* import android.widget.*
import androidx.core.widget.doOnTextChanged
import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import org.json.JSONArray import org.json.JSONArray
@ -27,6 +30,7 @@ class PeersActivity : AppCompatActivity() {
private lateinit var configuredTableLabel: TextView private lateinit var configuredTableLabel: TextView
private lateinit var multicastListenSwitch: Switch private lateinit var multicastListenSwitch: Switch
private lateinit var multicastBeaconSwitch: Switch private lateinit var multicastBeaconSwitch: Switch
private lateinit var passwordEdit: EditText
private lateinit var addPeerButton: ImageButton private lateinit var addPeerButton: ImageButton
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -62,6 +66,30 @@ class PeersActivity : AppCompatActivity() {
multicastListenPanel.setOnClickListener { multicastListenPanel.setOnClickListener {
multicastListenSwitch.toggle() 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 = findViewById(R.id.addPeerButton)
addPeerButton.setOnClickListener { addPeerButton.setOnClickListener {
@ -156,7 +184,7 @@ class PeersActivity : AppCompatActivity() {
val view = inflater.inflate(R.layout.peers_connected, null) val view = inflater.inflate(R.layout.peers_connected, null)
val ip = peer.getString("IP") val ip = peer.getString("IP")
view.findViewById<TextView>(R.id.addressLabel).text = 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) connectedTableLayout.addView(view)
} }
} }
@ -168,7 +196,9 @@ class PeersActivity : AppCompatActivity() {
when (intent.getStringExtra("type")) { when (intent.getStringExtra("type")) {
"state" -> { "state" -> {
if (intent.hasExtra("peers")) { 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 -> val array = Array(peersArray.length()) { i ->
peersArray.getJSONObject(i) peersArray.getJSONObject(i)
} }

View file

@ -1,8 +1,12 @@
package eu.neilalexander.yggdrasil package eu.neilalexander.yggdrasil
import android.app.AlertDialog import android.app.AlertDialog
import android.content.BroadcastReceiver
import android.content.ClipData import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
@ -13,6 +17,7 @@ import android.view.View
import android.widget.* import android.widget.*
import androidx.appcompat.widget.LinearLayoutCompat import androidx.appcompat.widget.LinearLayoutCompat
import androidx.core.widget.doOnTextChanged import androidx.core.widget.doOnTextChanged
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import org.json.JSONObject import org.json.JSONObject
class SettingsActivity : AppCompatActivity() { class SettingsActivity : AppCompatActivity() {
@ -87,11 +92,10 @@ class SettingsActivity : AppCompatActivity() {
val view = inflater.inflate(R.layout.dialog_set_keys, null) 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 builder: AlertDialog.Builder = AlertDialog.Builder(ContextThemeWrapper(this, R.style.Theme_MaterialComponents_DayNight_Dialog))
val privateKey = view.findViewById<EditText>(R.id.private_key) 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.setTitle(getString(R.string.set_keys))
builder.setView(view) builder.setView(view)
builder.setPositiveButton(getString(R.string.save)) { dialog, _ -> builder.setPositiveButton(getString(R.string.save)) { dialog, _ ->
config.setKeys(privateKey.text.toString(), publicKey.text.toString()) config.setKeys(privateKey.text.toString())
updateView() updateView()
dialog.dismiss() dialog.dismiss()
} }
@ -113,13 +117,40 @@ class SettingsActivity : AppCompatActivity() {
} }
private fun updateView() { private fun updateView() {
val nodeinfo = config.getJSON().optJSONObject("NodeInfo") val json = config.getJSON()
val nodeinfo = json.optJSONObject("NodeInfo")
if (nodeinfo != null) { if (nodeinfo != null) {
deviceNameEntry.setText(nodeinfo.getString("name"), TextView.BufferType.EDITABLE) deviceNameEntry.setText(nodeinfo.getString("name"), TextView.BufferType.EDITABLE)
} else { } else {
deviceNameEntry.setText("", TextView.BufferType.EDITABLE) 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")
}
}
}
} }
} }

View file

@ -210,11 +210,11 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:text="@string/main_coordinates" android:text="@string/main_tree_length"
android:textColor="?attr/textDefault" /> android:textColor="?attr/textDefault" />
<TextView <TextView
android:id="@+id/coordinatesValue" android:id="@+id/treeLengthValue"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
@ -224,7 +224,7 @@
android:scrollHorizontally="false" android:scrollHorizontally="false"
android:selectAllOnFocus="true" android:selectAllOnFocus="true"
android:singleLine="true" android:singleLine="true"
android:text="[]" android:text="0"
android:textAlignment="viewEnd" android:textAlignment="viewEnd"
android:textIsSelectable="true" /> android:textIsSelectable="true" />
</androidx.appcompat.widget.LinearLayoutCompat> </androidx.appcompat.widget.LinearLayoutCompat>

View file

@ -217,6 +217,37 @@
</TableRow> </TableRow>
<TableRow
android:id="@+id/passwordTableRow"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:paddingStart="4pt"
android:paddingTop="4pt"
android:paddingEnd="4pt"
android:paddingBottom="4pt">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/peers_multicast_password_hint"
android:textColor="?attr/textDefault" />
<EditText
android:id="@+id/passwordEdit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@null"
android:ems="10"
android:hint="@string/tap_to_edit"
android:inputType="textVisiblePassword"
android:padding="0pt"
android:textAlignment="textEnd"
android:textSize="14sp" />
</TableRow>
</TableLayout> </TableLayout>
<TextView <TextView

View file

@ -12,15 +12,6 @@
android:paddingTop="4pt" android:paddingTop="4pt"
android:paddingBottom="4pt"> android:paddingBottom="4pt">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/public_key_label" />
<EditText
android:id="@+id/public_key"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View file

@ -46,7 +46,7 @@
<string name="main_not_available">Н</string> <string name="main_not_available">Н</string>
<string name="main_ip">Адрес</string> <string name="main_ip">Адрес</string>
<string name="main_subnet">Подсеть</string> <string name="main_subnet">Подсеть</string>
<string name="main_coordinates">Координаты</string> <string name="main_tree_length">Высота дерева</string>
<string name="main_configuration">Конфигурация</string> <string name="main_configuration">Конфигурация</string>
<string name="main_peers">Пиры</string> <string name="main_peers">Пиры</string>
<string name="main_dns_servers">Серверы DNS</string> <string name="main_dns_servers">Серверы DNS</string>
@ -58,7 +58,8 @@
<string name="discoverable_over_multicast">Находимый через multicast</string> <string name="discoverable_over_multicast">Находимый через multicast</string>
<string name="search_for_multicast_peers">Искать пиров через multicast</string> <string name="search_for_multicast_peers">Искать пиров через multicast</string>
<string name="configured_peers_hint">Yggdrasil будет пытаться подключаться к этим пирам автоматически. Если вы добавите несколько пиров, ваше устройство может быть использовано для переноса данных между другими узлами сети. Чтобы этого избежать настройте только один пир.</string> <string name="configured_peers_hint">Yggdrasil будет пытаться подключаться к этим пирам автоматически. Если вы добавите несколько пиров, ваше устройство может быть использовано для переноса данных между другими узлами сети. Чтобы этого избежать настройте только один пир.</string>
<string name="peer_connectivity_hint">Пиры могут быть найдены с помощью Multicast если они находятся в той же Wi-Fi сети, либо через USB. Трафик в мобильной сети может быть платным. Вы можете отключить мобильные данные в настройках устройства.</string> <string name="peer_connectivity_hint">Пиры могут быть найдены с помощью Multicast если они находятся в той же Wi-Fi сети, либо через USB. У них должен быть одинаковый пароль. Трафик в мобильной сети может быть платным. Вы можете отключить мобильные данные в настройках устройства.</string>
<string name="peers_multicast_password_hint">Пароль</string>
<string name="node_info">Об узле</string> <string name="node_info">Об узле</string>
<string name="device_name">Название устройства</string> <string name="device_name">Название устройства</string>
<string name="tap_to_edit">Нажмите для изменения</string> <string name="tap_to_edit">Нажмите для изменения</string>
@ -79,8 +80,7 @@
<string name="channel_description">Главный канал нотификаций сервиса</string> <string name="channel_description">Главный канал нотификаций сервиса</string>
<string name="permission_notification_text">Нажмите здесь чтобы включить Yggdrasil.</string> <string name="permission_notification_text">Нажмите здесь чтобы включить Yggdrasil.</string>
<string name="add_peer_help">Введите полный URI пира для добавления. Yggdrasil будет автоматически подключаться к нему при запуске.</string> <string name="add_peer_help">Введите полный URI пира для добавления. Yggdrasil будет автоматически подключаться к нему при запуске.</string>
<string name="public_key_label">Публичный ключ:</string>
<string name="private_key_label">Приватный ключ:</string> <string name="private_key_label">Приватный ключ:</string>
<string name="set_keys">Установить свои ключи</string> <string name="set_keys">Установить свой ключ</string>
<string name="save">Сохранить</string> <string name="save">Сохранить</string>
</resources> </resources>

View file

@ -46,7 +46,7 @@
<string name="main_not_available">N/A</string> <string name="main_not_available">N/A</string>
<string name="main_ip">IP</string> <string name="main_ip">IP</string>
<string name="main_subnet">Subnet</string> <string name="main_subnet">Subnet</string>
<string name="main_coordinates">Coordinates</string> <string name="main_tree_length">Tree length</string>
<string name="main_configuration">Configuration</string> <string name="main_configuration">Configuration</string>
<string name="main_peers">Peers</string> <string name="main_peers">Peers</string>
<string name="main_dns_servers">DNS servers</string> <string name="main_dns_servers">DNS servers</string>
@ -58,7 +58,8 @@
<string name="discoverable_over_multicast">Discoverable over multicast</string> <string name="discoverable_over_multicast">Discoverable over multicast</string>
<string name="search_for_multicast_peers">Search for multicast peers</string> <string name="search_for_multicast_peers">Search for multicast peers</string>
<string name="configured_peers_hint">Yggdrasil will automatically attempt to connect to configured peers when started. If you configure more than one peer, your device may carry traffic on behalf of other network nodes. Avoid this by configuring only a single peer.</string> <string name="configured_peers_hint">Yggdrasil will automatically attempt to connect to configured peers when started. If you configure more than one peer, your device may carry traffic on behalf of other network nodes. Avoid this by configuring only a single peer.</string>
<string name="peer_connectivity_hint">Multicast peers will be discovered on the same Wi-Fi network or via USB. Data charges may apply when using mobile data. You can prevent data usage in the device settings.</string> <string name="peer_connectivity_hint">Multicast peers will be discovered on the same Wi-Fi network or via USB. They must have the same password. Data charges may apply when using mobile data. You can prevent data usage in the device settings.</string>
<string name="peers_multicast_password_hint">Password</string>
<string name="node_info">Node Info</string> <string name="node_info">Node Info</string>
<string name="device_name">Device Name</string> <string name="device_name">Device Name</string>
<string name="tap_to_edit">Tap to edit</string> <string name="tap_to_edit">Tap to edit</string>
@ -79,8 +80,7 @@
<string name="channel_description">Main channel for foreground notification</string> <string name="channel_description">Main channel for foreground notification</string>
<string name="permission_notification_text">Tap here to enable Yggdrasil.</string> <string name="permission_notification_text">Tap here to enable Yggdrasil.</string>
<string name="add_peer_help">Enter the full URI of the peer to add. Yggdrasil will automatically connect to this peer when started.</string> <string name="add_peer_help">Enter the full URI of the peer to add. Yggdrasil will automatically connect to this peer when started.</string>
<string name="public_key_label">Public key:</string>
<string name="private_key_label">Private key:</string> <string name="private_key_label">Private key:</string>
<string name="set_keys">Set your own keys</string> <string name="set_keys">Set your own key</string>
<string name="save">Save</string> <string name="save">Save</string>
</resources> </resources>

View file

@ -1,12 +1,12 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
ext.kotlin_version = '1.7.20' ext.kotlin_version = '1.9.10'
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath "com.android.tools.build:gradle:4.2.2" classpath 'com.android.tools.build:gradle:7.4.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong

View file

@ -1,6 +1,6 @@
#Mon Jun 14 15:11:35 BST 2021 #Sat Aug 26 21:38:34 CEST 2023
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

@ -1 +1 @@
Subproject commit 14f1cd4696a37b0f7fdcb067fac337c46953f8af Subproject commit 7f9d4f3f6d06262e212a8dd101d51fda134332da