From d3183bf37bb79920be3d4100a43546133a083f16 Mon Sep 17 00:00:00 2001 From: Niko Diamadis Date: Tue, 18 Jul 2023 22:08:36 +0200 Subject: [PATCH 1/6] Add explicit string template positions --- app/src/main/res/values/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 783a647..d58f147 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,8 +3,8 @@ Close navigation drawer Navigation header Found Gotify v%s - Request to \'%s\' failed with status code %d - Request to \'%s\' failed. %s. + Request to \'%1$s\' failed with status code %2$d + Request to \'%1$s\' failed. %2$s. There is no user with this username and password Client Name Choose a name for your session @@ -18,7 +18,7 @@ Oops Cannot connect to %s Server returned 401 unauthorized while trying to get current user. This can be caused by deleting the client for this session. - Could not get current user. Server (%s) responded with code %d: body (first 200 chars): %s + Could not get current user. Server (%1$s) responded with code %2$d: body (first 200 chars): %3$s User action required Please login, the authentication token isn\'t valid anymore. Connection closed @@ -59,7 +59,7 @@ Connected Could not connect Initializing - gotify/android v%s; gotify/server v%s + gotify/android v%1$s; gotify/server v%2$s Advanced Settings Done No certificate selected From 70c7375abbf31db673e6e64532a0ec27a7891151 Mon Sep 17 00:00:00 2001 From: Niko Diamadis Date: Tue, 18 Jul 2023 14:48:38 +0200 Subject: [PATCH 2/6] Replace deprecated onBackPressed with callback --- app/src/main/AndroidManifest.xml | 8 ++++++-- .../gotify/messages/MessagesActivity.kt | 20 ++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c975aaf..c131319 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,5 +1,7 @@ - + @@ -16,8 +18,10 @@ android:roundIcon="@mipmap/ic_launcher" android:supportsRtl="true" android:usesCleartextTraffic="true" + android:enableOnBackInvokedCallback="true" android:networkSecurityConfig="@xml/network_security_config" - android:theme="@style/AppTheme.SplashScreen"> + android:theme="@style/AppTheme.SplashScreen" + tools:targetApi="tiramisu"> updateAppOnDrawerClose = null @@ -135,6 +141,7 @@ internal class MessagesActivity : } invalidateOptionsMenu() } + onBackPressedCallback.isEnabled = false } } ) @@ -242,12 +249,15 @@ internal class MessagesActivity : refreshAll.setOnClickListener { refreshAll() } } - override fun onBackPressed() { - if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) { - binding.drawerLayout.closeDrawer(GravityCompat.START) - } else { - super.onBackPressed() + private fun addBackPressCallback() { + onBackPressedCallback = object : OnBackPressedCallback(false) { + override fun handleOnBackPressed() { + if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) { + binding.drawerLayout.closeDrawer(GravityCompat.START) + } + } } + onBackPressedDispatcher.addCallback(this, onBackPressedCallback) } override fun onNavigationItemSelected(item: MenuItem): Boolean { From 69fc25571acd7da368a62a6cb3012aa8189421ed Mon Sep 17 00:00:00 2001 From: Niko Diamadis Date: Tue, 18 Jul 2023 21:54:41 +0200 Subject: [PATCH 3/6] Replace deprecated ActivityResults with ResultLauncher --- .../com/github/gotify/login/LoginActivity.kt | 56 ++++++++----------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/app/src/main/kotlin/com/github/gotify/login/LoginActivity.kt b/app/src/main/kotlin/com/github/gotify/login/LoginActivity.kt index 402ffd0..77305c7 100644 --- a/app/src/main/kotlin/com/github/gotify/login/LoginActivity.kt +++ b/app/src/main/kotlin/com/github/gotify/login/LoginActivity.kt @@ -8,6 +8,7 @@ import android.os.Bundle import android.text.Editable import android.text.TextWatcher import android.view.View +import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity import com.github.gotify.R import com.github.gotify.SSLSettings @@ -35,11 +36,6 @@ import java.security.cert.X509Certificate import okhttp3.HttpUrl internal class LoginActivity : AppCompatActivity() { - companion object { - // return value from startActivityForResult when choosing a certificate - private const val FILE_SELECT_CODE = 1 - } - private lateinit var binding: ActivityLoginBinding private lateinit var settings: Settings @@ -47,6 +43,27 @@ internal class LoginActivity : AppCompatActivity() { private var caCertContents: String? = null private lateinit var advancedDialog: AdvancedDialog + private val certificateDialogResultLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> + try { + require(result.resultCode == RESULT_OK) { "result was ${result.resultCode}" } + requireNotNull(result.data) { "file path was null" } + + val uri = result.data!!.data ?: throw IllegalArgumentException("file path was null") + val fileStream = contentResolver.openInputStream(uri) + ?: throw IllegalArgumentException("file path was invalid") + + val content = Utils.readFileFromStream(fileStream) + val name = getNameOfCertContent(content) + + // temporarily set the contents (don't store to settings until they decide to login) + caCertContents = content + advancedDialog.showRemoveCACertificate(name) + } catch (e: Exception) { + Utils.showSnackBar(this, getString(R.string.select_ca_failed, e.message)) + } + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) UncaughtExceptionHandler.registerCurrentThread() @@ -152,9 +169,8 @@ internal class LoginActivity : AppCompatActivity() { intent.addCategory(Intent.CATEGORY_OPENABLE) try { - startActivityForResult( - Intent.createChooser(intent, getString(R.string.select_ca_file)), - FILE_SELECT_CODE + certificateDialogResultLauncher.launch( + Intent.createChooser(intent, getString(R.string.select_ca_file)) ) } catch (e: ActivityNotFoundException) { // case for user not having a file browser installed @@ -162,30 +178,6 @@ internal class LoginActivity : AppCompatActivity() { } } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - try { - if (requestCode == FILE_SELECT_CODE) { - require(resultCode == RESULT_OK) { "result was $resultCode" } - requireNotNull(data) { "file path was null" } - - val uri = data.data ?: throw IllegalArgumentException("file path was null") - - val fileStream = contentResolver.openInputStream(uri) - ?: throw IllegalArgumentException("file path was invalid") - - val content = Utils.readFileFromStream(fileStream) - val name = getNameOfCertContent(content) - - // temporarily set the contents (don't store to settings until they decide to login) - caCertContents = content - advancedDialog.showRemoveCACertificate(name) - } - } catch (e: Exception) { - Utils.showSnackBar(this, getString(R.string.select_ca_failed, e.message)) - } - } - private fun getNameOfCertContent(content: String): String { val ca = CertUtils.parseCertificate(content) return (ca as X509Certificate).subjectDN.name From 8c86e3f6221fdfef256da857d715b547eedd4558 Mon Sep 17 00:00:00 2001 From: Niko Diamadis Date: Mon, 24 Jul 2023 14:17:59 +0200 Subject: [PATCH 4/6] Remove logging of websocket connectivity --- .../com/github/gotify/service/WebSocketConnection.kt | 8 -------- .../kotlin/com/github/gotify/service/WebSocketService.kt | 1 - 2 files changed, 9 deletions(-) diff --git a/app/src/main/kotlin/com/github/gotify/service/WebSocketConnection.kt b/app/src/main/kotlin/com/github/gotify/service/WebSocketConnection.kt index 9ff0e4e..a92922b 100644 --- a/app/src/main/kotlin/com/github/gotify/service/WebSocketConnection.kt +++ b/app/src/main/kotlin/com/github/gotify/service/WebSocketConnection.kt @@ -1,7 +1,6 @@ package com.github.gotify.service import android.app.AlarmManager -import android.net.ConnectivityManager import android.os.Build import android.os.Handler import android.os.Looper @@ -24,7 +23,6 @@ internal class WebSocketConnection( private val baseUrl: String, settings: SSLSettings, private val token: String?, - private val connectivityManager: ConnectivityManager, private val alarmManager: AlarmManager ) { companion object { @@ -200,12 +198,6 @@ internal class WebSocketConnection( } errorCount++ - - val network = connectivityManager.activeNetworkInfo - if (network == null || !network.isConnected) { - Log.i("WebSocket($id): Network not connected") - } - val minutes = (errorCount * 2 - 1).coerceAtMost(20) onNetworkFailure.execute(minutes) diff --git a/app/src/main/kotlin/com/github/gotify/service/WebSocketService.kt b/app/src/main/kotlin/com/github/gotify/service/WebSocketService.kt index de63a91..69401df 100644 --- a/app/src/main/kotlin/com/github/gotify/service/WebSocketService.kt +++ b/app/src/main/kotlin/com/github/gotify/service/WebSocketService.kt @@ -113,7 +113,6 @@ internal class WebSocketService : Service() { settings.url, settings.sslSettings(), settings.token, - cm, alarmManager ) .onOpen { onOpen() } From 08cd963aeb38619b65287f6cad8520537f3475d5 Mon Sep 17 00:00:00 2001 From: Niko Diamadis Date: Mon, 24 Jul 2023 14:21:08 +0200 Subject: [PATCH 5/6] Suppress message model unchecked cast warning --- .../kotlin/com/github/gotify/messages/MessagesModelFactory.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/kotlin/com/github/gotify/messages/MessagesModelFactory.kt b/app/src/main/kotlin/com/github/gotify/messages/MessagesModelFactory.kt index 32d8def..d22e8c4 100644 --- a/app/src/main/kotlin/com/github/gotify/messages/MessagesModelFactory.kt +++ b/app/src/main/kotlin/com/github/gotify/messages/MessagesModelFactory.kt @@ -9,6 +9,7 @@ internal class MessagesModelFactory( ) : ViewModelProvider.Factory { override fun create(modelClass: Class): T { if (modelClass == MessagesModel::class.java) { + @Suppress("UNCHECKED_CAST") return modelClass.cast(MessagesModel(modelParameterActivity)) as T } throw IllegalArgumentException( From 74e1be13d3dd2b115ff468ef599e14f60c8c28f6 Mon Sep 17 00:00:00 2001 From: Niko Diamadis Date: Mon, 24 Jul 2023 14:30:03 +0200 Subject: [PATCH 6/6] Suppress setTargetFragment because of missing solution --- .../main/kotlin/com/github/gotify/settings/SettingsActivity.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/kotlin/com/github/gotify/settings/SettingsActivity.kt b/app/src/main/kotlin/com/github/gotify/settings/SettingsActivity.kt index 9cc1cb2..9f4ef92 100644 --- a/app/src/main/kotlin/com/github/gotify/settings/SettingsActivity.kt +++ b/app/src/main/kotlin/com/github/gotify/settings/SettingsActivity.kt @@ -110,6 +110,7 @@ internal class SettingsActivity : AppCompatActivity(), OnSharedPreferenceChangeL private fun showListPreferenceDialog(preference: ListPreference) { val dialogFragment = MaterialListPreference() dialogFragment.arguments = Bundle(1).apply { putString("key", preference.key) } + @Suppress("DEPRECATION") // https://issuetracker.google.com/issues/181793702#comment3 dialogFragment.setTargetFragment(this, 0) dialogFragment.show( parentFragmentManager,