ui: bifurcate only parts of release but nag about wrong context
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
f829b8abe0
commit
4156b83b84
@ -49,6 +49,10 @@ android {
|
|||||||
applicationIdSuffix = ".debug"
|
applicationIdSuffix = ".debug"
|
||||||
versionNameSuffix = "-debug"
|
versionNameSuffix = "-debug"
|
||||||
}
|
}
|
||||||
|
create("googleplay") {
|
||||||
|
initWith(getByName("release"))
|
||||||
|
matchingFallbacks += "release"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lint {
|
lint {
|
||||||
disable += "LongLogTag"
|
disable += "LongLogTag"
|
||||||
|
8
ui/src/googleplay/AndroidManifest.xml
Normal file
8
ui/src/googleplay/AndroidManifest.xml
Normal file
@ -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>
|
@ -5,7 +5,10 @@
|
|||||||
|
|
||||||
package com.wireguard.android.updater
|
package com.wireguard.android.updater
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
@ -27,10 +30,11 @@ class SnackbarUpdateShower(private val fragment: Fragment) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class SwapableSnackbar(fragment: Fragment, view: View, anchor: View?) {
|
private class SwapableSnackbar(fragment: Fragment, view: View, anchor: View?) {
|
||||||
val actionSnackbar = makeSnackbar(fragment, view, anchor)
|
private val actionSnackbar = makeSnackbar(fragment, view, anchor)
|
||||||
val statusSnackbar = makeSnackbar(fragment, view, anchor)
|
private val statusSnackbar = makeSnackbar(fragment, view, anchor)
|
||||||
var showingAction: Boolean = false
|
private var showingAction: Boolean = false
|
||||||
var showingStatus: Boolean = false
|
private var showingStatus: Boolean = false
|
||||||
|
private var permanentAction: Boolean = false
|
||||||
|
|
||||||
private fun makeSnackbar(fragment: Fragment, view: View, anchor: View?): Snackbar {
|
private fun makeSnackbar(fragment: Fragment, view: View, anchor: View?): Snackbar {
|
||||||
val snackbar = Snackbar.make(fragment.requireContext(), view, "", Snackbar.LENGTH_INDEFINITE)
|
val snackbar = Snackbar.make(fragment.requireContext(), view, "", Snackbar.LENGTH_INDEFINITE)
|
||||||
@ -45,7 +49,7 @@ class SnackbarUpdateShower(private val fragment: Fragment) {
|
|||||||
snackbar.addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() {
|
snackbar.addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() {
|
||||||
override fun onDismissed(snackbar: Snackbar?, @DismissEvent event: Int) {
|
override fun onDismissed(snackbar: Snackbar?, @DismissEvent event: Int) {
|
||||||
super.onDismissed(snackbar, event)
|
super.onDismissed(snackbar, event)
|
||||||
if (event == DISMISS_EVENT_MANUAL || event == DISMISS_EVENT_ACTION ||
|
if (event == DISMISS_EVENT_MANUAL || (event == DISMISS_EVENT_ACTION && !permanentAction) ||
|
||||||
(snackbar == actionSnackbar && !showingAction) || (snackbar == statusSnackbar && !showingStatus)
|
(snackbar == actionSnackbar && !showingAction) || (snackbar == statusSnackbar && !showingStatus)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
@ -58,11 +62,12 @@ class SnackbarUpdateShower(private val fragment: Fragment) {
|
|||||||
return snackbar
|
return snackbar
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showAction(text: String, action: String, listener: View.OnClickListener) {
|
fun showAction(text: String, action: String, permanent: Boolean = false, listener: View.OnClickListener) {
|
||||||
if (showingStatus) {
|
if (showingStatus) {
|
||||||
showingStatus = false
|
showingStatus = false
|
||||||
statusSnackbar.dismiss()
|
statusSnackbar.dismiss()
|
||||||
}
|
}
|
||||||
|
permanentAction = permanent
|
||||||
actionSnackbar.setText(text)
|
actionSnackbar.setText(text)
|
||||||
actionSnackbar.setAction(action, listener)
|
actionSnackbar.setAction(action, listener)
|
||||||
if (!showingAction) {
|
if (!showingAction) {
|
||||||
@ -141,6 +146,18 @@ class SnackbarUpdateShower(private val fragment: Fragment) {
|
|||||||
delay(5.seconds)
|
delay(5.seconds)
|
||||||
progress.retry()
|
progress.retry()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is Updater.Progress.Corrupt -> {
|
||||||
|
snackbar.showAction(context.getString(R.string.updater_corrupt), context.getString(R.string.updater_corrupt_navigate), true) {
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}.launchIn(fragment.lifecycleScope)
|
}.launchIn(fragment.lifecycleScope)
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,14 @@
|
|||||||
*/
|
*/
|
||||||
package com.wireguard.android.updater
|
package com.wireguard.android.updater
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.content.pm.PackageInstaller
|
import android.content.pm.PackageInstaller
|
||||||
|
import android.content.pm.PackageManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@ -116,6 +118,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)
|
private val mutableState = MutableStateFlow<Progress>(Progress.Complete)
|
||||||
@ -357,9 +364,29 @@ object Updater {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun monitorForUpdates() {
|
fun monitorForUpdates() {
|
||||||
if (installerIsGooglePlay(Application.get()))
|
val context = Application.get()
|
||||||
|
|
||||||
|
if (installerIsGooglePlay(context))
|
||||||
return
|
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 {
|
updaterScope.launch {
|
||||||
if (UserKnobs.updaterNewerVersionSeen.firstOrNull()?.let { Version(it) > CURRENT_VERSION } == true)
|
if (UserKnobs.updaterNewerVersionSeen.firstOrNull()?.let { Version(it) > CURRENT_VERSION } == true)
|
||||||
return@launch
|
return@launch
|
||||||
|
@ -236,6 +236,8 @@
|
|||||||
<string name="updater_download_progress_nototal">Downloading update: %s</string>
|
<string name="updater_download_progress_nototal">Downloading update: %s</string>
|
||||||
<string name="updater_installing">Installing update…</string>
|
<string name="updater_installing">Installing update…</string>
|
||||||
<string name="updater_failure">Update failure: %s. Will retry momentarily…</string>
|
<string name="updater_failure">Update failure: %s. Will retry momentarily…</string>
|
||||||
|
<string name="updater_corrupt">This application is corrupt. Please re-download it.</string>
|
||||||
|
<string name="updater_corrupt_navigate">Open Website</string>
|
||||||
<string name="version_summary">%1$s backend %2$s</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_checking">Checking %s backend version</string>
|
||||||
<string name="version_summary_unknown">Unknown %s version</string>
|
<string name="version_summary_unknown">Unknown %s version</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user