From 3de593dfd7eed11f0406ad520b20a73e830dd255 Mon Sep 17 00:00:00 2001 From: Ivan Date: Mon, 10 Jun 2019 14:52:37 +0200 Subject: [PATCH] Fixes: in position client to better handle lost connection with server quick sleep timer - use defaults, so can start without running dialog first. --- app/build.gradle | 4 +- .../eu/zderadicka/audioserve/MainActivity.kt | 4 +- .../fragments/ControllerFragment.kt | 6 ++- .../fragments/SleepDialogFragment.kt | 25 ++++-------- .../eu/zderadicka/audioserve/net/ApiClient.kt | 7 +++- .../audioserve/net/PositionClient.kt | 38 ++++++++++++++----- .../audioserve/ui/ExpandableFrameLayout.kt | 4 +- .../audioserve/utils/SleepService.kt | 29 ++++++++++++-- 8 files changed, 79 insertions(+), 38 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 81a9c03..2980974 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,8 +18,8 @@ android { applicationId "eu.zderadicka.audioserve" minSdkVersion 21 targetSdkVersion 28 - versionCode 33 - versionName "0.8.3" + versionCode 34 + versionName "0.8.4" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { diff --git a/app/src/main/java/eu/zderadicka/audioserve/MainActivity.kt b/app/src/main/java/eu/zderadicka/audioserve/MainActivity.kt index 4093193..1958a88 100644 --- a/app/src/main/java/eu/zderadicka/audioserve/MainActivity.kt +++ b/app/src/main/java/eu/zderadicka/audioserve/MainActivity.kt @@ -569,7 +569,9 @@ class MainActivity : AppCompatActivity(), items, err -> if (err!= null) { Log.e(LOG_TAG, "Error querying position $err") - Toast.makeText(this, "Cann't get remote position: $err",Toast.LENGTH_SHORT).show() + runOnUiThread { + Toast.makeText(this, "Cann't get remote position: $err", Toast.LENGTH_SHORT).show() + } } else { checkRemotePositions(items, false,null) } diff --git a/app/src/main/java/eu/zderadicka/audioserve/fragments/ControllerFragment.kt b/app/src/main/java/eu/zderadicka/audioserve/fragments/ControllerFragment.kt index 297c55a..67861c1 100644 --- a/app/src/main/java/eu/zderadicka/audioserve/fragments/ControllerFragment.kt +++ b/app/src/main/java/eu/zderadicka/audioserve/fragments/ControllerFragment.kt @@ -250,7 +250,11 @@ class ControllerFragment : MediaFragment(), SharedPreferences.OnSharedPreference if (err != null) { Log.e(LOG_TAG, "Error reading position: $err") //TODO: remove debug toasts - Toast.makeText(context, "Cann't get remote position: $err",Toast.LENGTH_SHORT).show() + activity?.also { + it.runOnUiThread { + Toast.makeText(context, "Cann't get remote position: $err", Toast.LENGTH_SHORT).show() + } + } transportControls?.play() } else if (!res.isNullOrEmpty()){ diff --git a/app/src/main/java/eu/zderadicka/audioserve/fragments/SleepDialogFragment.kt b/app/src/main/java/eu/zderadicka/audioserve/fragments/SleepDialogFragment.kt index 5c4423c..7b5b984 100644 --- a/app/src/main/java/eu/zderadicka/audioserve/fragments/SleepDialogFragment.kt +++ b/app/src/main/java/eu/zderadicka/audioserve/fragments/SleepDialogFragment.kt @@ -9,14 +9,14 @@ import android.support.v7.app.AlertDialog import android.widget.NumberPicker import android.widget.Switch import eu.zderadicka.audioserve.R +import eu.zderadicka.audioserve.utils.currentSleepExtendMins +import eu.zderadicka.audioserve.utils.currentSleepMins import eu.zderadicka.audioserve.utils.startSleepTimer // All four must be dividable by 5 private const val MAX_SLEEP = 120 -private const val DEFAULT_SLEEP = 30 -private const val MAX_EXTEND = 120 -private const val DEFAULT_EXTEND = 15 +private const val MAX_SLEEP_EXTEND = 120 private fun calcSteps (max:Int): Array { return (1..minsToVal(max)).map{ valToMins(it).toString()}.toTypedArray() @@ -39,23 +39,12 @@ class SleepDialogFragment : DialogFragment() { sleepAfterPicker.maxValue= minsToVal(MAX_SLEEP) sleepAfterPicker.wrapSelectorWheel = false extendByPicker.minValue=1 - extendByPicker.maxValue= minsToVal(MAX_EXTEND) + extendByPicker.maxValue= minsToVal(MAX_SLEEP_EXTEND) extendByPicker.wrapSelectorWheel = false sleepAfterPicker.displayedValues = calcSteps(MAX_SLEEP) - extendByPicker.displayedValues = calcSteps(MAX_EXTEND) - var currentSleep = sps.getInt("pref_sleep", -1) - if (currentSleep < 0) { - currentSleep = DEFAULT_SLEEP - sps.edit().putInt("pref_sleep", currentSleep).commit() - } - sleepAfterPicker.value = minsToVal(currentSleep) - - var currentExtend = sps.getInt("pref_extend", -1) - if (currentExtend < 0 ) { - currentExtend = DEFAULT_EXTEND - sps.edit().putInt("pref_extend", currentExtend).commit() - } - extendByPicker.value = minsToVal(currentExtend) + extendByPicker.displayedValues = calcSteps(MAX_SLEEP_EXTEND) + sleepAfterPicker.value = minsToVal(currentSleepMins(context!!)) + extendByPicker.value = minsToVal(currentSleepExtendMins(context!!)) sleepAfterPicker.setOnValueChangedListener{_, _, newValue -> sps.edit().putInt("pref_sleep", valToMins(newValue)).apply() } diff --git a/app/src/main/java/eu/zderadicka/audioserve/net/ApiClient.kt b/app/src/main/java/eu/zderadicka/audioserve/net/ApiClient.kt index 0b10890..7b52fbb 100644 --- a/app/src/main/java/eu/zderadicka/audioserve/net/ApiClient.kt +++ b/app/src/main/java/eu/zderadicka/audioserve/net/ApiClient.kt @@ -566,7 +566,12 @@ class ApiClient private constructor(val context: Context) { val err = ApiError.fromResponseError(it) if (err == ApiError.UnauthorizedAccess && token == null) { // started offline - try again to log in - login {} + login { + if (it == null && ! group.isNullOrEmpty()) { + //we logged in reinit positionClient + initPositionClient(true) + } + } } callback(null, err) diff --git a/app/src/main/java/eu/zderadicka/audioserve/net/PositionClient.kt b/app/src/main/java/eu/zderadicka/audioserve/net/PositionClient.kt index 90915b9..4bcb082 100644 --- a/app/src/main/java/eu/zderadicka/audioserve/net/PositionClient.kt +++ b/app/src/main/java/eu/zderadicka/audioserve/net/PositionClient.kt @@ -3,6 +3,7 @@ package eu.zderadicka.audioserve.net import android.net.Uri import android.os.Bundle import android.os.Handler +import android.os.Looper import android.support.v4.media.MediaBrowserCompat import android.support.v4.media.MediaDescriptionCompat import android.util.Log @@ -48,8 +49,11 @@ class PositionClient(val serverUrl:String, val token:String, val group: String?) // try to open the websocketsocket errors+=1; if (! closed) { + //extendTimeout for this pending query + setTimeout() close(stayClosed = false) open() + } else { finishPendingQuery(PositionClientError.Timeout) } @@ -60,6 +64,14 @@ class PositionClient(val serverUrl:String, val token:String, val group: String?) } + private fun setTimeout() { + handler.postDelayed(timeout, TIMEOUT_DURATION) + } + + private fun cancelTimeout() { + handler.removeCallbacks(timeout) + } + private val reopen = object : Runnable { override fun run() { open() @@ -103,26 +115,26 @@ class PositionClient(val serverUrl:String, val token:String, val group: String?) fun sendQuery(folderPath:String?, cb: PendingReceive) { finishPendingQuery(PositionClientError.CanceledByNext) - handler.removeCallbacks(timeout) + cancelTimeout() if (socket == null) { cb(null, PositionClientError.NotConnected) } else { socket?.apply { pendingQuery = PendingQuery(cb, folderPath, System.currentTimeMillis()) send(folderPath?: group!!) - handler.postDelayed(timeout, TIMEOUT_DURATION) + setTimeout() } } } private fun resendQuery() { - handler.removeCallbacks(timeout) + cancelTimeout() socket?.apply { pendingQuery?.apply { pendingQuery = PendingQuery(pendingReceive, query, System.currentTimeMillis()) send(query ?: group!!) - handler.postDelayed(timeout, TIMEOUT_DURATION) + setTimeout() } } } @@ -144,6 +156,7 @@ class PositionClient(val serverUrl:String, val token:String, val group: String?) handler.removeCallbacks(reopen) closed = stayClosed socket?.close(NORMAL_CLOSE, null) + socket=null } inner class SocketListener : WebSocketListener() { @@ -158,22 +171,23 @@ class PositionClient(val serverUrl:String, val token:String, val group: String?) override fun onOpen(webSocket: WebSocket, response: Response) { Log.d(LOG_TAG, "Socket opened") resetErrorInterval() - handler.removeCallbacks(timeout); + //cancelTimeout() handler.removeCallbacks(reopen); pendingQuery?.also { val currentTime = System.currentTimeMillis() if (currentTime - it.timeStamp < 2 * TIMEOUT_DURATION) resendQuery() + else finishPendingQuery(PositionClientError.Timeout) } } override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) { - Log.w(LOG_TAG, "Socket Error: $t") + Log.w(LOG_TAG, "Socket Error: $t pending query: $pendingQuery") pendingQuery?.also { //extend timeout, but only if it is first error if (it.errors == 0) { - handler.removeCallbacks(timeout) - handler.postDelayed(timeout, TIMEOUT_DURATION) + cancelTimeout() + setTimeout() } else { it.errors+=1 } @@ -195,7 +209,7 @@ class PositionClient(val serverUrl:String, val token:String, val group: String?) override fun onMessage(webSocket: WebSocket, text: String) { Log.d(LOG_TAG, "Got message $text") resetErrorInterval() - handler.removeCallbacks(timeout) + cancelTimeout() try { val res = parseRemotePositionResponse(text) pendingQuery?.pendingReceive?.invoke(res, null) @@ -220,7 +234,11 @@ class PositionClient(val serverUrl:String, val token:String, val group: String?) val query: String?, val timeStamp: Long, var errors: Int = 0 - ) + ) { + override fun toString(): String { + return "PendigQuery ts = $timeStamp, errors = $errors, query=$query" + } + } } diff --git a/app/src/main/java/eu/zderadicka/audioserve/ui/ExpandableFrameLayout.kt b/app/src/main/java/eu/zderadicka/audioserve/ui/ExpandableFrameLayout.kt index 86b0c89..f6bb481 100644 --- a/app/src/main/java/eu/zderadicka/audioserve/ui/ExpandableFrameLayout.kt +++ b/app/src/main/java/eu/zderadicka/audioserve/ui/ExpandableFrameLayout.kt @@ -65,7 +65,7 @@ class ExpandableFrameLayout @JvmOverloads constructor(context: Context, attrs: A override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean { val distY = e1.rawY - e2.rawY val distX = e1.rawX - e2.rawX - Log.d(LOG_TAG, "Scroll in Y $distY") + //Log.d(LOG_TAG, "Scroll in Y $distY") isDragging = true if (abs(distY) > abs(distX)) { if (distY > touchSlop && height < maxHeight) { @@ -98,7 +98,7 @@ class ExpandableFrameLayout @JvmOverloads constructor(context: Context, attrs: A } override fun onTouchEvent(event: MotionEvent): Boolean { - Log.d(LOG_TAG, "Player touch $event") + //Log.d(LOG_TAG, "Player touch $event") if (event.actionMasked == MotionEvent.ACTION_UP) { diff --git a/app/src/main/java/eu/zderadicka/audioserve/utils/SleepService.kt b/app/src/main/java/eu/zderadicka/audioserve/utils/SleepService.kt index a75b98a..dc6cf93 100644 --- a/app/src/main/java/eu/zderadicka/audioserve/utils/SleepService.kt +++ b/app/src/main/java/eu/zderadicka/audioserve/utils/SleepService.kt @@ -38,8 +38,32 @@ private const val minuteMillis = 60_000L private const val NOTIFICATION_ID = 74211 private const val LOG_TAG = "SleepService" +private const val DEFAULT_SLEEP = 30 +private const val DEFAULT_SLEEP_EXTEND = 15 + private const val MIN_G_FOR_ACTION = 1.5F +fun currentSleepMins(ctx: Context) : Int { + val sps = PreferenceManager.getDefaultSharedPreferences(ctx) + var currentSleep = sps.getInt("pref_sleep", -1) + if (currentSleep < 0) { + currentSleep = DEFAULT_SLEEP + sps.edit().putInt("pref_sleep", currentSleep).commit() + } + + return currentSleep +} + +fun currentSleepExtendMins(ctx: Context) : Int { + val sps = PreferenceManager.getDefaultSharedPreferences(ctx) + var currentExtend = sps.getInt("pref_extend", -1) + if (currentExtend < 0 ) { + currentExtend = DEFAULT_SLEEP_EXTEND + sps.edit().putInt("pref_extend", currentExtend).commit() + } + return currentExtend +} + fun cancelSleepTimer(context: Context) { val intent = Intent(context, SleepService::class.java) intent.action = SLEEP_CANCEL_ACTION @@ -102,9 +126,8 @@ class SleepService() : Service() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { when (intent?.action) { SLEEP_START_ACTION -> { - val time = prefs.getInt("pref_sleep", -1) + val time = currentSleepMins(this) if (time > 0) { - timer = MyTimer(time ) statusListener?.invoke(isRunning, time) timer?.startWithNotification() @@ -205,7 +228,7 @@ class SleepService() : Service() { } private fun extend() { - val time = prefs.getInt("pref_extend", -1) + val time = currentSleepExtendMins(this) if (time > 0 && timer != null) { val remains = timer?.remains?:0 timer?.cancel()