From 07b1da9de1040a06ed9d49a31b1393ca86aae0a5 Mon Sep 17 00:00:00 2001 From: Jannis Mattheis Date: Sat, 15 Feb 2025 11:45:12 +0100 Subject: [PATCH 1/2] fix: don't reconnect when command was superseded We only want to do the reconnect if the previous command was the schedule reconnect, if the websocket connection got started another way or was closed, we don't want to do the reconnect. --- .../gotify/service/WebSocketConnection.kt | 29 +++++++++++++++---- .../github/gotify/service/WebSocketService.kt | 5 +--- 2 files changed, 24 insertions(+), 10 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 5c55b0be..0199d565 100644 --- a/app/src/main/kotlin/com/github/gotify/service/WebSocketConnection.kt +++ b/app/src/main/kotlin/com/github/gotify/service/WebSocketConnection.kt @@ -1,6 +1,7 @@ package com.github.gotify.service import android.app.AlarmManager +import android.app.AlarmManager.OnAlarmListener import android.os.Build import android.os.Handler import android.os.Looper @@ -29,9 +30,10 @@ internal class WebSocketConnection( private val ID = AtomicLong(0) } + private var alarmManagerCallback: OnAlarmListener? = null + private var handlerCallback: Runnable? = null private val client: OkHttpClient private val reconnectHandler = Handler(Looper.getMainLooper()) - private val reconnectCallback = Runnable { start() } private var errorCount = 0 private var webSocket: WebSocket? = null @@ -106,6 +108,13 @@ internal class WebSocketConnection( @Synchronized fun close() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + alarmManagerCallback?.run(alarmManager::cancel) + alarmManagerCallback = null + } else { + handlerCallback?.run(reconnectHandler::removeCallbacks) + handlerCallback = null + } if (webSocket != null) { webSocket?.close(1000, "") closed() @@ -119,8 +128,10 @@ internal class WebSocketConnection( state = State.Disconnected } + fun scheduleReconnectNow(seconds: Long) = scheduleReconnect(ID.get(), seconds) + @Synchronized - fun scheduleReconnect(seconds: Long) { + fun scheduleReconnect(id: Long, seconds: Long) { if (state == State.Connecting || state == State.Connected) { return } @@ -130,17 +141,23 @@ internal class WebSocketConnection( Logger.info("WebSocket: scheduling a restart in $seconds second(s) (via alarm manager)") val future = Calendar.getInstance() future.add(Calendar.SECOND, seconds.toInt()) + + alarmManagerCallback?.run(alarmManager::cancel) + val cb = OnAlarmListener { syncExec(id) { start() } } + alarmManagerCallback = cb alarmManager.setExact( AlarmManager.RTC_WAKEUP, future.timeInMillis, "reconnect-tag", - { start() }, + cb, null ) } else { Logger.info("WebSocket: scheduling a restart in $seconds second(s)") - reconnectHandler.removeCallbacks(reconnectCallback) - reconnectHandler.postDelayed(reconnectCallback, TimeUnit.SECONDS.toMillis(seconds)) + handlerCallback?.run(reconnectHandler::removeCallbacks) + val cb = Runnable { syncExec(id) { start() } } + handlerCallback = cb + reconnectHandler.postDelayed(cb, TimeUnit.SECONDS.toMillis(seconds)) } } @@ -190,7 +207,7 @@ internal class WebSocketConnection( val minutes = (errorCount * 2 - 1).coerceAtMost(20) onFailure.execute(response?.message ?: "unreachable", minutes) - scheduleReconnect(TimeUnit.MINUTES.toSeconds(minutes.toLong())) + scheduleReconnect(id, TimeUnit.MINUTES.toSeconds(minutes.toLong())) } super.onFailure(webSocket, t, response) } 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 3bfc6984..60a37ddb 100644 --- a/app/src/main/kotlin/com/github/gotify/service/WebSocketService.kt +++ b/app/src/main/kotlin/com/github/gotify/service/WebSocketService.kt @@ -172,10 +172,7 @@ internal class WebSocketService : Service() { } private fun doReconnect() { - if (connection == null) { - return - } - connection!!.scheduleReconnect(15) + connection?.scheduleReconnectNow(15) } private fun onFailure(status: String, minutes: Int) { From 6968a659929b088d10e574e298ebe95b56f066a4 Mon Sep 17 00:00:00 2001 From: Jannis Mattheis Date: Sat, 15 Feb 2025 12:11:07 +0100 Subject: [PATCH 2/2] fix: use drawer layout in push This fixes https://github.com/gotify/android/pull/387#discussion_r1864875878 --- app/src/main/res/layout/activity_share.xml | 263 +++++++++++---------- 1 file changed, 139 insertions(+), 124 deletions(-) diff --git a/app/src/main/res/layout/activity_share.xml b/app/src/main/res/layout/activity_share.xml index 4779e411..89058e25 100644 --- a/app/src/main/res/layout/activity_share.xml +++ b/app/src/main/res/layout/activity_share.xml @@ -1,137 +1,152 @@ - + android:fitsSystemWindows="true" + tools:openDrawer="start"> - + android:layout_height="match_parent"> - - - + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> - - - - - - - - - + android:orientation="vertical"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + android:layout_height="wrap_content" /> + + \ No newline at end of file