diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b987347e8dfa0345780742e44da9ca16e4992135..226aa378c09e8bd1fc9e89a9e60e669c392a1f3a 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -34,8 +34,8 @@ plugins { } android { - compileSdkVersion(27) - buildToolsVersion("27.0.3") + compileSdkVersion(28) + buildToolsVersion("28.0.0") signingConfigs { val signing = project.rootProject.properties("signing.properties") @@ -51,7 +51,7 @@ android { defaultConfig { minSdkVersion(16) - targetSdkVersion(27) + targetSdkVersion(28) applicationId = "com.iskrembilen.quasseldroid" versionCode = cmd("git", "rev-list", "--count", "HEAD")?.toIntOrNull() ?: 1 diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/AndroidHeartBeatRunner.kt b/app/src/main/java/de/kuschku/quasseldroid/service/AndroidHeartBeatRunner.kt new file mode 100644 index 0000000000000000000000000000000000000000..21ba09a302b1052d8c938a99b3a6bdb3c5f022e8 --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid/service/AndroidHeartBeatRunner.kt @@ -0,0 +1,46 @@ +package de.kuschku.quasseldroid.service + +import android.os.Handler +import de.kuschku.libquassel.protocol.message.SignalProxyMessage +import de.kuschku.libquassel.session.HeartBeatRunner +import de.kuschku.libquassel.session.Session +import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log +import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.INFO +import org.threeten.bp.Duration +import org.threeten.bp.Instant + +class AndroidHeartBeatRunner( + private val session: Session, + private val handler: Handler +) : HeartBeatRunner { + private var running = true + private var lastHeartBeatReply: Instant = Instant.now() + + override fun start() { + if (running) { + val now = Instant.now() + val duration = Duration.between(lastHeartBeatReply, now).toMillis() + if (duration > TIMEOUT) { + log(INFO, "Heartbeat", "Ping Timeout: Last Response ${duration}ms ago") + session.close() + } else { + log(INFO, "Heartbeat", "Sending Heartbeat") + session.dispatch(SignalProxyMessage.HeartBeat(now)) + } + handler.postDelayed(::start, DELAY) + } + } + + override fun end() { + running = false + } + + override fun setLastHeartBeatReply(time: Instant) { + this.lastHeartBeatReply = time + } + + companion object { + const val TIMEOUT = 120_000L + const val DELAY = 30_000L + } +} diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt index a2b53fbd56338177b87941e2fc31f12eb4df16b4..59c51fe6a3321f026481c9f3456c3815f8b31bab 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt @@ -22,6 +22,7 @@ package de.kuschku.quasseldroid.service import android.arch.lifecycle.Observer import android.content.* import android.net.ConnectivityManager +import android.os.Handler import android.support.v4.app.RemoteInput import android.text.SpannableString import de.kuschku.libquassel.connection.ConnectionState @@ -312,6 +313,7 @@ class QuasselService : DaggerLifecycleService(), QuasselBacklogStorage(database), notificationBackend, handlerService, + { session: Session -> AndroidHeartBeatRunner(session, Handler()) }, ::disconnectFromCore, ::initCallback, CrashHandler::handle diff --git a/app/src/main/res/values/strings_licenses.xml b/app/src/main/res/values/strings_licenses.xml index 554cc5309a8a97b4d732a1e24a61218958156b86..916aa0becb19fdfd348afb110624bd2b2ead6dfe 100644 --- a/app/src/main/res/values/strings_licenses.xml +++ b/app/src/main/res/values/strings_licenses.xml @@ -102,7 +102,7 @@ <p>a. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(c), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(c), as requested.</p> <p>b. You may Distribute or Publicly Perform an Adaptation only under the terms of: (i) this License; (ii) a later version of this License with the same License Elements as this License; (iii) a Creative Commons jurisdiction license (either this or a later license version) that contains the same License Elements as this License (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible License. If you license the Adaptation under one of the licenses mentioned in (iv), you must comply with the terms of that license. If you license the Adaptation under the terms of any of the licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), you must comply with the terms of the Applicable License generally and the following provisions: (I) You must include a copy of, or the URI for, the Applicable License with every copy of each Adaptation You Distribute or Publicly Perform; (II) You may not offer or impose any terms on the Adaptation that restrict the terms of the Applicable License or the ability of the recipient of the Adaptation to exercise the rights granted to that recipient under the terms of the Applicable License; (III) You must keep intact all notices that refer to the Applicable License and to the disclaimer of warranties with every copy of the Work as included in the Adaptation You Distribute or Publicly Perform; (IV) when You Distribute or Publicly Perform the Adaptation, You may not impose any effective technological measures on the Adaptation that restrict the ability of a recipient of the Adaptation from You to exercise the rights granted to that recipient under the terms of the Applicable License. This Section 4(b) applies to the Adaptation as incorporated in a Collection, but this does not require the Collection apart from the Adaptation itself to be made subject to the terms of the Applicable License.</p> <p>c. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor\'s copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Ssection 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4(c) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.</p> - <p>d. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise.</p> + <p>d. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author\'s honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author\'s honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise.</p> <p><strong>5. Representations, Warranties and Disclaimer</strong></p> <p>UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.</p> <p><strong>6. Limitation on Liability.</strong>EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</p> diff --git a/lib/src/main/java/de/kuschku/libquassel/session/HeartBeatRunner.kt b/lib/src/main/java/de/kuschku/libquassel/session/HeartBeatRunner.kt new file mode 100644 index 0000000000000000000000000000000000000000..d59696be0b6fb9bc06efb7df8b74d067729d288b --- /dev/null +++ b/lib/src/main/java/de/kuschku/libquassel/session/HeartBeatRunner.kt @@ -0,0 +1,15 @@ +package de.kuschku.libquassel.session + +import org.threeten.bp.Instant + +interface HeartBeatRunner { + fun start() + fun end() + + fun setLastHeartBeatReply(time: Instant) + + companion object { + const val TIMEOUT = 120_000L + const val DELAY = 30_000L + } +} diff --git a/lib/src/main/java/de/kuschku/libquassel/session/HeartBeatThread.kt b/lib/src/main/java/de/kuschku/libquassel/session/JavaHeartBeatRunner.kt similarity index 79% rename from lib/src/main/java/de/kuschku/libquassel/session/HeartBeatThread.kt rename to lib/src/main/java/de/kuschku/libquassel/session/JavaHeartBeatRunner.kt index b5661f80020a90823195442581cbbbfef29938d6..b5ae349a6e2fe2a3ce4ee9e83ff1953d5937d49f 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/HeartBeatThread.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/JavaHeartBeatRunner.kt @@ -6,10 +6,13 @@ import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.INFO import org.threeten.bp.Duration import org.threeten.bp.Instant -class HeartBeatThread(private val session: Session) : Thread() { +class JavaHeartBeatRunner( + private val session: Session +) : Thread(), HeartBeatRunner { private var running = true private var lastHeartBeatReply: Instant = Instant.now() - override fun run() { + + override fun start() { while (running) { val now = Instant.now() val duration = Duration.between(lastHeartBeatReply, now).toMillis() @@ -20,20 +23,20 @@ class HeartBeatThread(private val session: Session) : Thread() { log(INFO, "Heartbeat", "Sending Heartbeat") session.dispatch(SignalProxyMessage.HeartBeat(now)) } - Thread.sleep(30_000) + Thread.sleep(DELAY) } } - fun end() { + override fun end() { running = false } - fun setLastHeartBeatReply(time: Instant) { + override fun setLastHeartBeatReply(time: Instant) { this.lastHeartBeatReply = time } companion object { - // Timeout, set to 2 minutes const val TIMEOUT = 120_000L + const val DELAY = 30_000L } } diff --git a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt index e2dabf554ea11519168666d4a986b8077138608b..e7710038fb29a5713b265d1fafeb4f4c5eb0a15a 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt @@ -45,6 +45,7 @@ class Session( backlogStorage: BacklogStorage, private val notificationManager: NotificationManager?, private var userData: Pair<String, String>, + heartBeatFactory: (Session) -> HeartBeatRunner, val disconnectFromCore: () -> Unit, private val initCallback: (Session) -> Unit, exceptionHandler: (Throwable) -> Unit @@ -92,7 +93,7 @@ class Session( override val lag = BehaviorSubject.createDefault(0L) - private val heartBeatThread = HeartBeatThread(this) + private val heartBeatThread = heartBeatFactory(this) init { coreConnection.start() diff --git a/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt b/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt index a56e736cd83bca37daefb6859ba5edb96811f284..fccae0ba2e99f4b26e9ce4d7a737f20beed76d07 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt @@ -41,6 +41,7 @@ class SessionManager( private val backlogStorage: BacklogStorage, private val notificationManager: NotificationManager?, val handlerService: HandlerService, + private val heartBeatFactory: (Session) -> HeartBeatRunner, private val disconnectFromCore: () -> Unit, private val initCallback: (Session) -> Unit, private val exceptionHandler: (Throwable) -> Unit @@ -131,6 +132,7 @@ class SessionManager( backlogStorage, notificationManager, userData, + heartBeatFactory, disconnectFromCore, initCallback, exceptionHandler diff --git a/malheur/build.gradle.kts b/malheur/build.gradle.kts index fc17e561a997791118997ad049d62409e7bab9e1..3c7d79c5cf1c9d64dcc30b5be43feca17dc96558 100644 --- a/malheur/build.gradle.kts +++ b/malheur/build.gradle.kts @@ -23,12 +23,12 @@ plugins { } android { - compileSdkVersion(27) - buildToolsVersion("27.0.3") + compileSdkVersion(28) + buildToolsVersion("28.0.0") defaultConfig { minSdkVersion(14) - targetSdkVersion(27) + targetSdkVersion(28) consumerProguardFiles("proguard-rules.pro") diff --git a/persistence/build.gradle.kts b/persistence/build.gradle.kts index 2e071b3285e41b1a7297e84f6afa37f05aed68b0..5b6d07e2f0a06bbd4ef69eb94906d07c33deadef 100644 --- a/persistence/build.gradle.kts +++ b/persistence/build.gradle.kts @@ -24,12 +24,12 @@ plugins { } android { - compileSdkVersion(27) - buildToolsVersion("27.0.3") + compileSdkVersion(28) + buildToolsVersion("28.0.0") defaultConfig { minSdkVersion(16) - targetSdkVersion(27) + targetSdkVersion(28) consumerProguardFiles("proguard-rules.pro") diff --git a/viewmodel/build.gradle.kts b/viewmodel/build.gradle.kts index 58451d75d0f4648968342667b30f296591a9462f..de116f3272fd139faf23fa3cad67f1aac43ceb3f 100644 --- a/viewmodel/build.gradle.kts +++ b/viewmodel/build.gradle.kts @@ -23,12 +23,12 @@ plugins { } android { - compileSdkVersion(27) - buildToolsVersion("27.0.3") + compileSdkVersion(28) + buildToolsVersion("28.0.0") defaultConfig { minSdkVersion(16) - targetSdkVersion(27) + targetSdkVersion(28) consumerProguardFiles("proguard-rules.pro")