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
|
package com.github.gotify.service
|
||||||
|
|
||||||
import android.app.AlarmManager
|
import android.app.AlarmManager
|
||||||
|
import android.app.AlarmManager.OnAlarmListener
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
@@ -29,9 +30,10 @@ internal class WebSocketConnection(
|
|||||||
private val ID = AtomicLong(0)
|
private val ID = AtomicLong(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var alarmManagerCallback: OnAlarmListener? = null
|
||||||
|
private var handlerCallback: Runnable? = null
|
||||||
private val client: OkHttpClient
|
private val client: OkHttpClient
|
||||||
private val reconnectHandler = Handler(Looper.getMainLooper())
|
private val reconnectHandler = Handler(Looper.getMainLooper())
|
||||||
private val reconnectCallback = Runnable { start() }
|
|
||||||
private var errorCount = 0
|
private var errorCount = 0
|
||||||
|
|
||||||
private var webSocket: WebSocket? = null
|
private var webSocket: WebSocket? = null
|
||||||
@@ -106,6 +108,13 @@ internal class WebSocketConnection(
|
|||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun close() {
|
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) {
|
if (webSocket != null) {
|
||||||
webSocket?.close(1000, "")
|
webSocket?.close(1000, "")
|
||||||
closed()
|
closed()
|
||||||
@@ -119,8 +128,10 @@ internal class WebSocketConnection(
|
|||||||
state = State.Disconnected
|
state = State.Disconnected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun scheduleReconnectNow(seconds: Long) = scheduleReconnect(ID.get(), seconds)
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun scheduleReconnect(seconds: Long) {
|
fun scheduleReconnect(id: Long, seconds: Long) {
|
||||||
if (state == State.Connecting || state == State.Connected) {
|
if (state == State.Connecting || state == State.Connected) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -130,17 +141,23 @@ internal class WebSocketConnection(
|
|||||||
Logger.info("WebSocket: scheduling a restart in $seconds second(s) (via alarm manager)")
|
Logger.info("WebSocket: scheduling a restart in $seconds second(s) (via alarm manager)")
|
||||||
val future = Calendar.getInstance()
|
val future = Calendar.getInstance()
|
||||||
future.add(Calendar.SECOND, seconds.toInt())
|
future.add(Calendar.SECOND, seconds.toInt())
|
||||||
|
|
||||||
|
alarmManagerCallback?.run(alarmManager::cancel)
|
||||||
|
val cb = OnAlarmListener { syncExec(id) { start() } }
|
||||||
|
alarmManagerCallback = cb
|
||||||
alarmManager.setExact(
|
alarmManager.setExact(
|
||||||
AlarmManager.RTC_WAKEUP,
|
AlarmManager.RTC_WAKEUP,
|
||||||
future.timeInMillis,
|
future.timeInMillis,
|
||||||
"reconnect-tag",
|
"reconnect-tag",
|
||||||
{ start() },
|
cb,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Logger.info("WebSocket: scheduling a restart in $seconds second(s)")
|
Logger.info("WebSocket: scheduling a restart in $seconds second(s)")
|
||||||
reconnectHandler.removeCallbacks(reconnectCallback)
|
handlerCallback?.run(reconnectHandler::removeCallbacks)
|
||||||
reconnectHandler.postDelayed(reconnectCallback, TimeUnit.SECONDS.toMillis(seconds))
|
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)
|
val minutes = (errorCount * 2 - 1).coerceAtMost(20)
|
||||||
|
|
||||||
onFailure.execute(response?.message ?: "unreachable", minutes)
|
onFailure.execute(response?.message ?: "unreachable", minutes)
|
||||||
scheduleReconnect(TimeUnit.MINUTES.toSeconds(minutes.toLong()))
|
scheduleReconnect(id, TimeUnit.MINUTES.toSeconds(minutes.toLong()))
|
||||||
}
|
}
|
||||||
super.onFailure(webSocket, t, response)
|
super.onFailure(webSocket, t, response)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,10 +172,7 @@ internal class WebSocketService : Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun doReconnect() {
|
private fun doReconnect() {
|
||||||
if (connection == null) {
|
connection?.scheduleReconnectNow(15)
|
||||||
return
|
|
||||||
}
|
|
||||||
connection!!.scheduleReconnect(15)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onFailure(status: String, minutes: Int) {
|
private fun onFailure(status: String, minutes: Int) {
|
||||||
|
|||||||
@@ -1,137 +1,152 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ScrollView
|
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
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_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true"
|
||||||
|
tools:openDrawer="start">
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent">
|
||||||
android:orientation="vertical">
|
|
||||||
|
<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">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="20dp">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ems="10"
|
||||||
|
android:hint="@string/push_title_hint"
|
||||||
|
android:inputType="text"
|
||||||
|
android:singleLine="true" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="20dp"
|
||||||
|
android:layout_marginBottom="20dp">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/push_content_hint"
|
||||||
|
android:inputType="textCapSentences|textMultiLine"
|
||||||
|
android:maxLength="2000"
|
||||||
|
android:maxLines="10" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="20dp"
|
||||||
|
android:layout_marginBottom="20dp">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/edtTxtPriority"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:digits="0123456789"
|
||||||
|
android:hint="@string/push_priority_hint"
|
||||||
|
android:imeOptions="actionDone"
|
||||||
|
android:inputType="numberSigned"
|
||||||
|
android:maxLength="3"
|
||||||
|
android:text="0" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="20dp"
|
||||||
|
android:layout_marginBottom="20dp">
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/txtAppListDesc"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/appListDescription" />
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/appSpinner"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:spinnerMode="dropdown"
|
||||||
|
android:textSize="18sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/missingAppsContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="20dp"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingStart="10dp"
|
||||||
|
android:paddingEnd="10dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/missingAppsIcon"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0"
|
||||||
|
app:srcCompat="@drawable/ic_info" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="10dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0" />
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/missingAppsText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0"
|
||||||
|
android:text="@string/push_missing_app_info"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:visibility="visible" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/push_button"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical|center_horizontal"
|
||||||
|
android:layout_marginHorizontal="20dp"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
android:text="@string/push_button"
|
||||||
|
android:textColor="@android:color/white" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
<include
|
<include
|
||||||
android:id="@+id/app_bar_drawer"
|
android:id="@+id/app_bar_drawer"
|
||||||
layout="@layout/app_bar_drawer"
|
layout="@layout/app_bar_drawer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
</androidx.drawerlayout.widget.DrawerLayout>
|
||||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="20dp">
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
|
||||||
android:id="@+id/title"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:hint="@string/push_title_hint"
|
|
||||||
android:inputType="text"
|
|
||||||
android:singleLine="true" />
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
|
||||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginHorizontal="20dp"
|
|
||||||
android:layout_marginBottom="20dp">
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
|
||||||
android:id="@+id/content"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:hint="@string/push_content_hint"
|
|
||||||
android:inputType="textCapSentences|textMultiLine"
|
|
||||||
android:maxLength="2000"
|
|
||||||
android:maxLines="10" />
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
|
||||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginHorizontal="20dp"
|
|
||||||
android:layout_marginBottom="20dp">
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
|
||||||
android:id="@+id/edtTxtPriority"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:digits="0123456789"
|
|
||||||
android:hint="@string/push_priority_hint"
|
|
||||||
android:imeOptions="actionDone"
|
|
||||||
android:inputType="numberSigned"
|
|
||||||
android:maxLength="3"
|
|
||||||
android:text="0" />
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginHorizontal="20dp"
|
|
||||||
android:layout_marginBottom="20dp">
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/txtAppListDesc"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/appListDescription" />
|
|
||||||
|
|
||||||
<Spinner
|
|
||||||
android:id="@+id/appSpinner"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="50dp"
|
|
||||||
android:spinnerMode="dropdown"
|
|
||||||
android:textSize="18sp" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/missingAppsContainer"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginHorizontal="20dp"
|
|
||||||
android:layout_marginBottom="20dp"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingStart="10dp"
|
|
||||||
android:paddingEnd="10dp"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/missingAppsIcon"
|
|
||||||
android:layout_width="40dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="0"
|
|
||||||
app:srcCompat="@drawable/ic_info" />
|
|
||||||
|
|
||||||
<Space
|
|
||||||
android:layout_width="10dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="0" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/missingAppsText"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="0"
|
|
||||||
android:text="@string/push_missing_app_info"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:visibility="visible" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/push_button"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
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" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</ScrollView>
|
|
||||||
Reference in New Issue
Block a user