Merge pull request #401 from gotify/fixes
fix: reconnecting with wrong url/credentials in the background after logout
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/drawer_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true">
|
||||
android:fitsSystemWindows="true"
|
||||
tools:openDrawer="start">
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:id="@+id/app_bar_drawer"
|
||||
layout="@layout/app_bar_drawer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
@@ -130,8 +135,18 @@
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:text="@string/push_button" />
|
||||
android:text="@string/push_button"
|
||||
android:textColor="@android:color/white" />
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<include
|
||||
android:id="@+id/app_bar_drawer"
|
||||
layout="@layout/app_bar_drawer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
||||
Reference in New Issue
Block a user