mirror of
https://github.com/amnezia-vpn/amneziawg-android.git
synced 2026-07-03 14:05:13 +02:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5fa2e6164f | |||
| 9972d9607e | |||
| 6a72194106 | |||
| 254e6164d7 | |||
| 675386241b | |||
| 8671acc1a6 | |||
| fb08bb6bd4 | |||
| 70f8e5ab3a | |||
| e53a8d76f9 | |||
| e0b4551bca | |||
| 7b9757bf3b | |||
| 4156b83b84 | |||
| f829b8abe0 | |||
| 838e0bd6b0 |
+2
-2
@@ -1,5 +1,5 @@
|
||||
wireguardVersionCode=503
|
||||
wireguardVersionName=1.0.20230508
|
||||
wireguardVersionCode=505
|
||||
wireguardVersionName=1.0.20230512
|
||||
wireguardPackageName=com.wireguard.android
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[versions]
|
||||
agp = "8.0.1"
|
||||
agp = "8.1.0-beta02"
|
||||
kotlin = "1.8.21"
|
||||
|
||||
[libraries]
|
||||
@@ -16,10 +16,10 @@ androidx-fragment-ktx = "androidx.fragment:fragment-ktx:1.5.7"
|
||||
androidx-lifecycle-runtime-ktx = "androidx.lifecycle:lifecycle-runtime-ktx:2.6.1"
|
||||
androidx-preference-ktx = "androidx.preference:preference-ktx:1.2.0"
|
||||
desugarJdkLibs = "com.android.tools:desugar_jdk_libs:2.0.3"
|
||||
google-material = "com.google.android.material:material:1.8.0"
|
||||
google-material = "com.google.android.material:material:1.9.0"
|
||||
jsr305 = "com.google.code.findbugs:jsr305:3.0.2"
|
||||
junit = "junit:junit:4.13.2"
|
||||
kotlinx-coroutines-android = "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
|
||||
kotlinx-coroutines-android = "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.0"
|
||||
zxing-android-embedded = "com.journeyapps:zxing-android-embedded:4.3.0"
|
||||
|
||||
[plugins]
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import com.android.build.gradle.tasks.GenerateLocaleConfigTask
|
||||
|
||||
// Grotesque workaround for https://issuetracker.google.com/issues/279780940
|
||||
System.setProperty("com.android.tools.r8.disableApiModeling", "1")
|
||||
|
||||
val pkg: String = providers.gradleProperty("wireguardPackageName").get()
|
||||
|
||||
@@ -41,6 +45,7 @@ android {
|
||||
resources {
|
||||
excludes += "DebugProbesKt.bin"
|
||||
excludes += "kotlin-tooling-metadata.json"
|
||||
excludes += "META-INF/*.version"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,6 +53,13 @@ android {
|
||||
applicationIdSuffix = ".debug"
|
||||
versionNameSuffix = "-debug"
|
||||
}
|
||||
create("googleplay") {
|
||||
initWith(getByName("release"))
|
||||
matchingFallbacks += "release"
|
||||
}
|
||||
}
|
||||
androidResources {
|
||||
generateLocaleConfig = true
|
||||
}
|
||||
lint {
|
||||
disable += "LongLogTag"
|
||||
@@ -83,3 +95,14 @@ tasks.withType<JavaCompile>().configureEach {
|
||||
tasks.withType<KotlinCompile>().configureEach {
|
||||
compilerOptions.jvmTarget.set(JvmTarget.JVM_17)
|
||||
}
|
||||
|
||||
// Grotesque workaround for https://issuetracker.google.com/issues/281825213
|
||||
tasks.withType<GenerateLocaleConfigTask>().configureEach {
|
||||
doLast {
|
||||
localeConfig.asFileTree.files.forEach {
|
||||
val lines = it.readLines()
|
||||
val newLines = lines.subList(0, 2) + lines.subList(2, lines.size - 1).sorted() + lines.last()
|
||||
it.writeText(newLines.joinToString(separator = "\n"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission
|
||||
android:name="android.permission.REQUEST_INSTALL_PACKAGES"
|
||||
tools:node="remove" />
|
||||
</manifest>
|
||||
@@ -143,6 +143,10 @@
|
||||
<meta-data
|
||||
android:name="android.service.quicksettings.ACTIVE_TILE"
|
||||
android:value="false" />
|
||||
|
||||
<meta-data
|
||||
android:name="android.service.quicksettings.TOGGLEABLE_TILE"
|
||||
android:value="true" />
|
||||
</service>
|
||||
|
||||
<meta-data
|
||||
|
||||
@@ -49,32 +49,31 @@ class QuickTileService : TileService() {
|
||||
}
|
||||
|
||||
override fun onClick() {
|
||||
if (tunnel != null) {
|
||||
unlockAndRun {
|
||||
val tile = qsTile
|
||||
if (tile != null) {
|
||||
tile.icon = if (tile.icon == iconOn) iconOff else iconOn
|
||||
tile.updateTile()
|
||||
}
|
||||
applicationScope.launch {
|
||||
try {
|
||||
tunnel!!.setStateAsync(Tunnel.State.TOGGLE)
|
||||
updateTile()
|
||||
} catch (_: Throwable) {
|
||||
val toggleIntent = Intent(this@QuickTileService, TunnelToggleActivity::class.java)
|
||||
toggleIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
startActivity(toggleIntent)
|
||||
when (val tunnel = tunnel) {
|
||||
null -> {
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
startActivityAndCollapse(intent)
|
||||
}
|
||||
else -> {
|
||||
unlockAndRun {
|
||||
applicationScope.launch {
|
||||
try {
|
||||
tunnel.setStateAsync(Tunnel.State.TOGGLE)
|
||||
updateTile()
|
||||
} catch (_: Throwable) {
|
||||
val toggleIntent = Intent(this@QuickTileService, TunnelToggleActivity::class.java)
|
||||
toggleIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
startActivity(toggleIntent)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
startActivityAndCollapse(intent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
isAdded = true
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
iconOn = Icon.createWithResource(this, R.drawable.ic_tile)
|
||||
iconOff = iconOn
|
||||
@@ -83,56 +82,65 @@ class QuickTileService : TileService() {
|
||||
val icon = SlashDrawable(resources.getDrawable(R.drawable.ic_tile, Application.get().theme))
|
||||
icon.setAnimationEnabled(false) /* Unfortunately we can't have animations, since Icons are marshaled. */
|
||||
icon.setSlashed(false)
|
||||
var b = Bitmap.createBitmap(icon.intrinsicWidth, icon.intrinsicHeight, Bitmap.Config.ARGB_8888)
|
||||
?: return
|
||||
var b = Bitmap.createBitmap(icon.intrinsicWidth, icon.intrinsicHeight, Bitmap.Config.ARGB_8888) ?: return
|
||||
var c = Canvas(b)
|
||||
icon.setBounds(0, 0, c.width, c.height)
|
||||
icon.draw(c)
|
||||
iconOn = Icon.createWithBitmap(b)
|
||||
icon.setSlashed(true)
|
||||
b = Bitmap.createBitmap(icon.intrinsicWidth, icon.intrinsicHeight, Bitmap.Config.ARGB_8888)
|
||||
?: return
|
||||
b = Bitmap.createBitmap(icon.intrinsicWidth, icon.intrinsicHeight, Bitmap.Config.ARGB_8888) ?: return
|
||||
c = Canvas(b)
|
||||
icon.setBounds(0, 0, c.width, c.height)
|
||||
icon.draw(c)
|
||||
iconOff = Icon.createWithBitmap(b)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
isAdded = false
|
||||
}
|
||||
|
||||
override fun onStartListening() {
|
||||
Application.getTunnelManager().addOnPropertyChangedCallback(onTunnelChangedCallback)
|
||||
if (tunnel != null) tunnel!!.addOnPropertyChangedCallback(onStateChangedCallback)
|
||||
tunnel?.addOnPropertyChangedCallback(onStateChangedCallback)
|
||||
updateTile()
|
||||
}
|
||||
|
||||
override fun onStopListening() {
|
||||
if (tunnel != null) tunnel!!.removeOnPropertyChangedCallback(onStateChangedCallback)
|
||||
tunnel?.removeOnPropertyChangedCallback(onStateChangedCallback)
|
||||
Application.getTunnelManager().removeOnPropertyChangedCallback(onTunnelChangedCallback)
|
||||
}
|
||||
|
||||
override fun onTileAdded() {
|
||||
isAdded = true
|
||||
}
|
||||
|
||||
override fun onTileRemoved() {
|
||||
isAdded = false
|
||||
}
|
||||
|
||||
private fun updateTile() {
|
||||
// Update the tunnel.
|
||||
val newTunnel = Application.getTunnelManager().lastUsedTunnel
|
||||
if (newTunnel != tunnel) {
|
||||
if (tunnel != null) tunnel!!.removeOnPropertyChangedCallback(onStateChangedCallback)
|
||||
tunnel?.removeOnPropertyChangedCallback(onStateChangedCallback)
|
||||
tunnel = newTunnel
|
||||
if (tunnel != null) tunnel!!.addOnPropertyChangedCallback(onStateChangedCallback)
|
||||
tunnel?.addOnPropertyChangedCallback(onStateChangedCallback)
|
||||
}
|
||||
// Update the tile contents.
|
||||
val label: String
|
||||
val state: Int
|
||||
val tile = qsTile
|
||||
if (tunnel != null) {
|
||||
label = tunnel!!.name
|
||||
state = if (tunnel!!.state == Tunnel.State.UP) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE
|
||||
} else {
|
||||
label = getString(R.string.app_name)
|
||||
state = Tile.STATE_INACTIVE
|
||||
}
|
||||
if (tile == null) return
|
||||
tile.label = label
|
||||
if (tile.state != state) {
|
||||
tile.icon = if (state == Tile.STATE_ACTIVE) iconOn else iconOff
|
||||
tile.state = state
|
||||
val tile = qsTile ?: return
|
||||
|
||||
when (val tunnel = tunnel) {
|
||||
null -> {
|
||||
tile.label = getString(R.string.app_name)
|
||||
tile.state = Tile.STATE_INACTIVE
|
||||
tile.icon = iconOff
|
||||
}
|
||||
else -> {
|
||||
tile.label = tunnel.name
|
||||
tile.state = if (tunnel.state == Tunnel.State.UP) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE
|
||||
tile.icon = if (tunnel.state == Tunnel.State.UP) iconOn else iconOff
|
||||
}
|
||||
}
|
||||
tile.updateTile()
|
||||
}
|
||||
@@ -143,19 +151,23 @@ class QuickTileService : TileService() {
|
||||
sender.removeOnPropertyChangedCallback(this)
|
||||
return
|
||||
}
|
||||
if (propertyId != 0 && propertyId != BR.state) return
|
||||
if (propertyId != 0 && propertyId != BR.state)
|
||||
return
|
||||
updateTile()
|
||||
}
|
||||
}
|
||||
|
||||
private inner class OnTunnelChangedCallback : OnPropertyChangedCallback() {
|
||||
override fun onPropertyChanged(sender: Observable, propertyId: Int) {
|
||||
if (propertyId != 0 && propertyId != BR.lastUsedTunnel) return
|
||||
if (propertyId != 0 && propertyId != BR.lastUsedTunnel)
|
||||
return
|
||||
updateTile()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "WireGuard/QuickTileService"
|
||||
var isAdded: Boolean = false
|
||||
private set
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
*/
|
||||
package com.wireguard.android.activity
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.service.quicksettings.TileService
|
||||
import android.view.MenuItem
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.commit
|
||||
@@ -14,6 +16,7 @@ import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.wireguard.android.Application
|
||||
import com.wireguard.android.QuickTileService
|
||||
import com.wireguard.android.R
|
||||
import com.wireguard.android.backend.WgQuickBackend
|
||||
import com.wireguard.android.preference.PreferencesPreferenceDataStore
|
||||
@@ -47,7 +50,13 @@ class SettingsActivity : AppCompatActivity() {
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, key: String?) {
|
||||
preferenceManager.preferenceDataStore = PreferencesPreferenceDataStore(lifecycleScope, Application.getPreferencesDataStore())
|
||||
addPreferencesFromResource(R.xml.preferences)
|
||||
preferenceScreen.initialExpandedChildrenCount = 4
|
||||
preferenceScreen.initialExpandedChildrenCount = 5
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || QuickTileService.isAdded) {
|
||||
val quickTile = preferenceManager.findPreference<Preference>("quick_tile")
|
||||
quickTile?.parent?.removePreference(quickTile)
|
||||
--preferenceScreen.initialExpandedChildrenCount
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
val darkTheme = preferenceManager.findPreference<Preference>("dark_theme")
|
||||
darkTheme?.parent?.removePreference(darkTheme)
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.wireguard.android.preference
|
||||
|
||||
import android.app.StatusBarManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Build
|
||||
import android.util.AttributeSet
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.preference.Preference
|
||||
import com.wireguard.android.QuickTileService
|
||||
import com.wireguard.android.R
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
||||
class QuickTilePreference(context: Context, attrs: AttributeSet?) : Preference(context, attrs) {
|
||||
override fun getSummary() = context.getString(R.string.quick_settings_tile_add_summary)
|
||||
|
||||
override fun getTitle() = context.getString(R.string.quick_settings_tile_add_title)
|
||||
|
||||
override fun onClick() {
|
||||
val statusBarManager = context.getSystemService(StatusBarManager::class.java)
|
||||
statusBarManager.requestAddTileService(
|
||||
ComponentName(context, QuickTileService::class.java),
|
||||
context.getString(R.string.quick_settings_tile_action),
|
||||
Icon.createWithResource(context, R.drawable.ic_tile),
|
||||
context.mainExecutor
|
||||
) {
|
||||
when (it) {
|
||||
StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_ALREADY_ADDED,
|
||||
StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_ADDED -> {
|
||||
parent?.removePreference(this)
|
||||
--preferenceManager.preferenceScreen.initialExpandedChildrenCount
|
||||
}
|
||||
StatusBarManager.TILE_ADD_REQUEST_ERROR_MISMATCHED_PACKAGE,
|
||||
StatusBarManager.TILE_ADD_REQUEST_ERROR_REQUEST_IN_PROGRESS,
|
||||
StatusBarManager.TILE_ADD_REQUEST_ERROR_BAD_COMPONENT,
|
||||
StatusBarManager.TILE_ADD_REQUEST_ERROR_NOT_CURRENT_USER,
|
||||
StatusBarManager.TILE_ADD_REQUEST_ERROR_APP_NOT_IN_FOREGROUND,
|
||||
StatusBarManager.TILE_ADD_REQUEST_ERROR_NO_STATUS_BAR_SERVICE ->
|
||||
Toast.makeText(context, context.getString(R.string.quick_settings_tile_add_failure, it), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,14 @@
|
||||
|
||||
package com.wireguard.android.updater
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.snackbar.BaseTransientBottomBar
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.wireguard.android.R
|
||||
@@ -27,10 +31,10 @@ class SnackbarUpdateShower(private val fragment: Fragment) {
|
||||
}
|
||||
|
||||
private class SwapableSnackbar(fragment: Fragment, view: View, anchor: View?) {
|
||||
val actionSnackbar = makeSnackbar(fragment, view, anchor)
|
||||
val statusSnackbar = makeSnackbar(fragment, view, anchor)
|
||||
var showingAction: Boolean = false
|
||||
var showingStatus: Boolean = false
|
||||
private val actionSnackbar = makeSnackbar(fragment, view, anchor)
|
||||
private val statusSnackbar = makeSnackbar(fragment, view, anchor)
|
||||
private var showingAction: Boolean = false
|
||||
private var showingStatus: Boolean = false
|
||||
|
||||
private fun makeSnackbar(fragment: Fragment, view: View, anchor: View?): Snackbar {
|
||||
val snackbar = Snackbar.make(fragment.requireContext(), view, "", Snackbar.LENGTH_INDEFINITE)
|
||||
@@ -141,6 +145,28 @@ class SnackbarUpdateShower(private val fragment: Fragment) {
|
||||
delay(5.seconds)
|
||||
progress.retry()
|
||||
}
|
||||
|
||||
is Updater.Progress.Corrupt -> {
|
||||
MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.updater_corrupt_title)
|
||||
.setMessage(R.string.updater_corrupt_message)
|
||||
.setPositiveButton(R.string.updater_corrupt_navigate) { _, _ ->
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
intent.data = Uri.parse(progress.downloadUrl)
|
||||
try {
|
||||
context.startActivity(intent)
|
||||
} catch (e: Throwable) {
|
||||
Toast.makeText(context, ErrorMessages[e], Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}.setCancelable(false).setOnDismissListener {
|
||||
val intent = Intent(Intent.ACTION_MAIN)
|
||||
intent.addCategory(Intent.CATEGORY_HOME)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
context.startActivity(intent)
|
||||
System.exit(0)
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
}.launchIn(fragment.lifecycleScope)
|
||||
}
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
*/
|
||||
package com.wireguard.android.updater
|
||||
|
||||
import android.Manifest
|
||||
import android.app.PendingIntent
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.pm.PackageInstaller
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import android.util.Base64
|
||||
import android.util.Log
|
||||
@@ -19,6 +21,7 @@ import com.wireguard.android.Application
|
||||
import com.wireguard.android.BuildConfig
|
||||
import com.wireguard.android.activity.MainActivity
|
||||
import com.wireguard.android.util.UserKnobs
|
||||
import com.wireguard.android.util.applicationScope
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
@@ -74,7 +77,7 @@ object Updater {
|
||||
object Complete : Progress()
|
||||
class Available(val version: String) : Progress() {
|
||||
fun update() {
|
||||
Application.getCoroutineScope().launch {
|
||||
applicationScope.launch {
|
||||
UserKnobs.setUpdaterNewerVersionConsented(version)
|
||||
}
|
||||
}
|
||||
@@ -98,7 +101,7 @@ object Updater {
|
||||
}
|
||||
|
||||
fun markAsDone() {
|
||||
Application.getCoroutineScope().launch {
|
||||
applicationScope.launch {
|
||||
if (installerActive())
|
||||
return@launch
|
||||
delay(7.seconds)
|
||||
@@ -116,6 +119,11 @@ object Updater {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Corrupt(private val betterFile: String?) : Progress() {
|
||||
val downloadUrl: String
|
||||
get() = UPDATE_URL_FMT.format(betterFile ?: "")
|
||||
}
|
||||
}
|
||||
|
||||
private val mutableState = MutableStateFlow<Progress>(Progress.Complete)
|
||||
@@ -326,13 +334,13 @@ object Updater {
|
||||
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
|
||||
val id = intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID, 0)
|
||||
val userIntervention = IntentCompat.getParcelableExtra(intent, Intent.EXTRA_INTENT, Intent::class.java)!!
|
||||
Application.getCoroutineScope().launch {
|
||||
applicationScope.launch {
|
||||
emitProgress(Progress.NeedsUserIntervention(userIntervention, id))
|
||||
}
|
||||
}
|
||||
|
||||
PackageInstaller.STATUS_SUCCESS -> {
|
||||
Application.getCoroutineScope().launch {
|
||||
applicationScope.launch {
|
||||
emitProgress(Progress.Complete)
|
||||
}
|
||||
context.applicationContext.unregisterReceiver(this)
|
||||
@@ -345,7 +353,7 @@ object Updater {
|
||||
} catch (_: SecurityException) {
|
||||
}
|
||||
val message = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) ?: "Installation error $status"
|
||||
Application.getCoroutineScope().launch {
|
||||
applicationScope.launch {
|
||||
val e = Exception(message)
|
||||
Log.e(TAG, "Update failure", e)
|
||||
emitProgress(Progress.Failure(e))
|
||||
@@ -357,9 +365,29 @@ object Updater {
|
||||
}
|
||||
|
||||
fun monitorForUpdates() {
|
||||
if (installerIsGooglePlay(Application.get()))
|
||||
val context = Application.get()
|
||||
|
||||
if (installerIsGooglePlay(context))
|
||||
return
|
||||
|
||||
if (!if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
|
||||
@Suppress("DEPRECATION")
|
||||
context.packageManager.getPackageInfo(context.packageName, PackageManager.GET_PERMISSIONS)
|
||||
} else {
|
||||
context.packageManager.getPackageInfo(context.packageName, PackageManager.PackageInfoFlags.of(PackageManager.GET_PERMISSIONS.toLong()))
|
||||
}.requestedPermissions.contains(Manifest.permission.REQUEST_INSTALL_PACKAGES)
|
||||
) {
|
||||
updaterScope.launch {
|
||||
val update = try {
|
||||
checkForUpdates()
|
||||
} catch (_: Throwable) {
|
||||
null
|
||||
}
|
||||
emitProgress(Progress.Corrupt(update?.fileName))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
updaterScope.launch {
|
||||
if (UserKnobs.updaterNewerVersionSeen.firstOrNull()?.let { Version(it) > CURRENT_VERSION } == true)
|
||||
return@launch
|
||||
@@ -387,14 +415,14 @@ object Updater {
|
||||
UserKnobs.updaterNewerVersionConsented.firstOrNull()?.let { Version(it) > CURRENT_VERSION } != true
|
||||
)
|
||||
emitProgress(Progress.Available(ver))
|
||||
}.launchIn(Application.getCoroutineScope())
|
||||
}.launchIn(applicationScope)
|
||||
|
||||
UserKnobs.updaterNewerVersionConsented.onEach { ver ->
|
||||
if (ver != null && Version(ver) > CURRENT_VERSION)
|
||||
updaterScope.launch {
|
||||
downloadAndUpdateWrapErrors()
|
||||
}
|
||||
}.launchIn(Application.getCoroutineScope())
|
||||
}.launchIn(applicationScope)
|
||||
}
|
||||
|
||||
class AppUpdatedReceiver : BroadcastReceiver() {
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
unqualifiedResLocale=en-US
|
||||
@@ -119,6 +119,7 @@
|
||||
<string name="error_down">Fehler beim Abschalten des Tunnels: %s</string>
|
||||
<string name="error_fetching_apps">Fehler beim Abrufen der App-Liste: %s</string>
|
||||
<string name="error_root">Bitte root-Zugriff anfordern und erneut versuchen</string>
|
||||
<string name="error_prepare">Fehler beim Vorbereiten des Tunnels: %s</string>
|
||||
<string name="error_up">Fehler beim Starten des Tunnels: %s</string>
|
||||
<string name="exclude_private_ips">Private IPs ausschließen</string>
|
||||
<string name="generate_new_private_key">Neuen privaten Schlüssel generieren</string>
|
||||
@@ -138,6 +139,8 @@
|
||||
<string name="key_length_explanation_base64">: WireGuard base64-Schlüssel müssen 44 Zeichen enthalten (32 Bytes)</string>
|
||||
<string name="key_length_explanation_binary">: WireGuard-Schlüssel müssen 32 Bytes groß sein</string>
|
||||
<string name="key_length_explanation_hex">: WireGuard Hex-Schlüssel müssen 64 Zeichen (32 Bytes) groß sein</string>
|
||||
<string name="latest_handshake">Letzter Handshake</string>
|
||||
<string name="latest_handshake_ago">vor %s</string>
|
||||
<string name="listen_port">Eingangs-Port</string>
|
||||
<string name="log_export_error">Konnte Protokoll nicht exportieren: %s</string>
|
||||
<string name="log_export_subject">WireGuard Android Protokolldatei</string>
|
||||
@@ -216,6 +219,7 @@
|
||||
<string name="tunnel_create_success">Tunnel „%s “ erfolgreich erstellt</string>
|
||||
<string name="tunnel_error_already_exists">Tunnel „%s“ existiert bereits</string>
|
||||
<string name="tunnel_error_invalid_name">Ungültiger Name</string>
|
||||
<string name="tunnel_list_placeholder">Füge einen Tunnel mit der Schaltfläche unten hinzu</string>
|
||||
<string name="tunnel_name">Tunnelname</string>
|
||||
<string name="tunnel_on_error">Tunnel kann nicht eingeschaltet werden (wgTurnOn gab %d zurück)</string>
|
||||
<string name="tunnel_dns_failure">DNS-Hostname kann nicht aufgelöst werden: „%s“</string>
|
||||
@@ -224,6 +228,13 @@
|
||||
<string name="type_name_go_userspace">Go userspace</string>
|
||||
<string name="type_name_kernel_module">Kernelmodul</string>
|
||||
<string name="unknown_error">Unbekannter Fehler</string>
|
||||
<string name="updater_avalable">Ein Anwendungsupdate ist verfügbar. Bitte jetzt aktualisieren.</string>
|
||||
<string name="updater_action">Download & Update</string>
|
||||
<string name="updater_rechecking">Update-Metadaten abrufen…</string>
|
||||
<string name="updater_download_progress">Update wird heruntergeladen: %1$s / %2$s (%3$.2f%%)</string>
|
||||
<string name="updater_download_progress_nototal">Update wird heruntergeladen: %s</string>
|
||||
<string name="updater_installing">Installiere Update…</string>
|
||||
<string name="updater_failure">Fehler beim Aktualisieren: %s. Versuche es in Kürze erneut…</string>
|
||||
<string name="version_summary">%1$s backend %2$s</string>
|
||||
<string name="version_summary_checking">Überprüfe %s Backend-Version</string>
|
||||
<string name="version_summary_unknown">Unbekannte %s Version</string>
|
||||
|
||||
@@ -229,6 +229,13 @@ Aitäh veelkord sinu panuse eest.</string>
|
||||
<string name="type_name_go_userspace">Go kasutajamaa</string>
|
||||
<string name="type_name_kernel_module">Tuumamoodul</string>
|
||||
<string name="unknown_error">Tundmatu viga</string>
|
||||
<string name="updater_avalable">Rakenduse uuendus on saadaval. Palun uuenda nüüd.</string>
|
||||
<string name="updater_action">Laadi alla ja uuenda</string>
|
||||
<string name="updater_rechecking">Uuenduse andmete laadimine…</string>
|
||||
<string name="updater_download_progress">Uuenduse allalaadimine: %1$s / %2$s (%3$.2f%%)</string>
|
||||
<string name="updater_download_progress_nototal">Uuenduse allalaadimine: %s</string>
|
||||
<string name="updater_installing">Uuenduse paigaldamine…</string>
|
||||
<string name="updater_failure">Uuendamine ebaõnnestus: %s. Uus katse hetke pärast…</string>
|
||||
<string name="version_summary">%1$s taustsüsteem %2$s</string>
|
||||
<string name="version_summary_checking">Kontrollin %s taustsüsteemi versiooni</string>
|
||||
<string name="version_summary_unknown">Tundmatu %s versioon</string>
|
||||
|
||||
@@ -254,6 +254,13 @@
|
||||
<string name="type_name_go_userspace">Пользовательское пространство Go</string>
|
||||
<string name="type_name_kernel_module">Модуль ядра</string>
|
||||
<string name="unknown_error">Неизвестная ошибка</string>
|
||||
<string name="updater_avalable">Доступно обновление приложения. Пожалуйста, обновите.</string>
|
||||
<string name="updater_action">Загрузить и установить</string>
|
||||
<string name="updater_rechecking">Получение метаданных обновления…</string>
|
||||
<string name="updater_download_progress">Загрузка обновления: %1$s / %2$s (%3$.2f%%)</string>
|
||||
<string name="updater_download_progress_nototal">Загрузка обновления: %s</string>
|
||||
<string name="updater_installing">Установка обновления…</string>
|
||||
<string name="updater_failure">Ошибка обновления: %s. Повторите попытку…</string>
|
||||
<string name="version_summary">%1$s бэкенд %2$s</string>
|
||||
<string name="version_summary_checking">Проверка версии бэкэнда %s</string>
|
||||
<string name="version_summary_unknown">Неизвестная версия %s</string>
|
||||
|
||||
@@ -215,6 +215,13 @@
|
||||
<string name="type_name_go_userspace">Go userspace</string>
|
||||
<string name="type_name_kernel_module">Kernel module</string>
|
||||
<string name="unknown_error">未知错误</string>
|
||||
<string name="updater_avalable">有可用的应用程序更新。请立即更新。</string>
|
||||
<string name="updater_action">下载 & 更新</string>
|
||||
<string name="updater_rechecking">正获取更新元数据…</string>
|
||||
<string name="updater_download_progress">正在下载更新: %1$s / %2$s (%3$.2f%%)</string>
|
||||
<string name="updater_download_progress_nototal">正在下载更新: %s</string>
|
||||
<string name="updater_installing">安装更新中...</string>
|
||||
<string name="updater_failure">更新失败: %s。不久后将重试…</string>
|
||||
<string name="version_summary">%1$s backend %2$s</string>
|
||||
<string name="version_summary_checking">正在检查 %s backend 版本</string>
|
||||
<string name="version_summary_unknown">未知的 %s 版本</string>
|
||||
|
||||
@@ -185,6 +185,10 @@
|
||||
<string name="private_key">Private key</string>
|
||||
<string name="public_key">Public key</string>
|
||||
<string name="qr_code_hint">Tip: generate with `qrencode -t ansiutf8 < tunnel.conf`.</string>
|
||||
<string name="quick_settings_tile_add_title">Add tile to quick settings panel</string>
|
||||
<string name="quick_settings_tile_add_summary">The shortcut tile toggles the most recent tunnel</string>
|
||||
<string name="quick_settings_tile_add_failure">Unable to add shortcut tile: error %d</string>
|
||||
<string name="quick_settings_tile_action">Toggle tunnel</string>
|
||||
<string name="restore_on_boot_summary_off">Will not bring up enabled tunnels at boot</string>
|
||||
<string name="restore_on_boot_summary_on">Will bring up enabled tunnels at boot</string>
|
||||
<string name="restore_on_boot_title">Restore on boot</string>
|
||||
@@ -236,6 +240,9 @@
|
||||
<string name="updater_download_progress_nototal">Downloading update: %s</string>
|
||||
<string name="updater_installing">Installing update…</string>
|
||||
<string name="updater_failure">Update failure: %s. Will retry momentarily…</string>
|
||||
<string name="updater_corrupt_title">Application Corrupt</string>
|
||||
<string name="updater_corrupt_message">This application is corrupt. Please re-download the APK from the website linked below. After, uninstall this application, and reinstall it from downloaded APK.</string>
|
||||
<string name="updater_corrupt_navigate">Open Website</string>
|
||||
<string name="version_summary">%1$s backend %2$s</string>
|
||||
<string name="version_summary_checking">Checking %s backend version</string>
|
||||
<string name="version_summary_unknown">Unknown %s version</string>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
android:summaryOn="@string/restore_on_boot_summary_on"
|
||||
android:title="@string/restore_on_boot_title" />
|
||||
<com.wireguard.android.preference.ZipExporterPreference android:key="zip_exporter" />
|
||||
<com.wireguard.android.preference.QuickTilePreference android:key="quick_tile" />
|
||||
<Preference
|
||||
android:key="log_viewer"
|
||||
android:singleLineTitle="false"
|
||||
|
||||
Reference in New Issue
Block a user