From 7b10813d3355f245fa3c85d823fae5b824f659a0 Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Thu, 29 Mar 2018 02:17:06 +0200
Subject: [PATCH] Support for disconnectFromCore feature

---
 .../quasseldroid/service/QuasselService.kt      | 15 ++++++++++++++-
 .../libquassel/quassel/QuasselFeature.kt        |  4 +++-
 .../libquassel/quassel/syncables/RpcHandler.kt  | 17 ++++++-----------
 .../de/kuschku/libquassel/session/Session.kt    |  3 ++-
 .../libquassel/session/SessionManager.kt        | 12 ++++++++----
 .../de/kuschku/libquassel/ConnectionUnitTest.kt |  8 ++++----
 6 files changed, 37 insertions(+), 22 deletions(-)

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 307d996fa..33a0e723e 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt
@@ -19,6 +19,7 @@ import de.kuschku.quasseldroid.util.QuasseldroidNotificationManager
 import de.kuschku.quasseldroid.util.backport.DaggerLifecycleService
 import de.kuschku.quasseldroid.util.compatibility.AndroidHandlerService
 import de.kuschku.quasseldroid.util.helper.editApply
+import de.kuschku.quasseldroid.util.helper.editCommit
 import de.kuschku.quasseldroid.util.helper.sharedPreferences
 import de.kuschku.quasseldroid.util.helper.toLiveData
 import io.reactivex.Observable
@@ -253,9 +254,21 @@ class QuasselService : DaggerLifecycleService(),
   }
   private val connectivity = BehaviorSubject.createDefault(Unit)
 
+  private fun disconnectFromCore() {
+    getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE).editCommit {
+      putBoolean(Keys.Status.reconnect, false)
+    }
+  }
+
   override fun onCreate() {
     super.onCreate()
-    sessionManager = SessionManager(ISession.NULL, QuasselBacklogStorage(database), handlerService)
+    sessionManager = SessionManager(
+      ISession.NULL,
+      QuasselBacklogStorage(database),
+      handlerService,
+      ::disconnectFromCore
+    )
+
     clientData = ClientData(
       identifier = "${resources.getString(R.string.app_name)} ${BuildConfig.VERSION_NAME}",
       buildDate = Instant.ofEpochSecond(BuildConfig.GIT_COMMIT_DATE),
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/QuasselFeature.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/QuasselFeature.kt
index b33835fb9..fdda7bf83 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/QuasselFeature.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/QuasselFeature.kt
@@ -35,7 +35,9 @@ enum class QuasselFeature(override val bit: Int) : Flag<QuasselFeature> {
   /** Core-Side highlight configuration and matching */
   CoreSideHighlights(0x1000),
   /** Show prefixes for senders in backlog */
-  SenderPrefixes(0x2000);
+  SenderPrefixes(0x2000),
+  /** Supports RPC call disconnectFromCore to remotely disconnect a client */
+  RemoteDisconnect(0x4000);
 
   companion object : Flags.Factory<QuasselFeature> {
     override val NONE: Flags<QuasselFeature> = QuasselFeature.of()
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt
index 60ad4a78a..649dd2da9 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt
@@ -37,8 +37,7 @@ class RpcHandler(
   override fun passwordChanged(ignored: Long, success: Boolean) {
   }
 
-  override fun disconnectFromCore() {
-  }
+  override fun disconnectFromCore() = session.disconnectFromCore()
 
   override fun objectRenamed(classname: ByteBuffer, newname: String, oldname: String) {
     session.renameObject(classname.deserializeString(StringSerializer.UTF8) ?: "", newname, oldname)
@@ -64,16 +63,12 @@ class RpcHandler(
   override fun requestPasswordChange(peerPtr: Long, user: String, old: String, new: String) {
   }
 
-  override fun requestKickClient(id: Int) {
-    RPC("2requestKickClient(Int)", ARG(id, Type.Int))
-  }
+  override fun requestKickClient(id: Int) = RPC("2requestKickClient(Int)", ARG(id, Type.Int))
 
-  override fun sendInput(bufferInfo: BufferInfo, message: String) {
-    RPC(
-      "2sendInput(BufferInfo,QString)", ARG(bufferInfo, QType.BufferInfo),
-      ARG(message, Type.QString)
-    )
-  }
+  override fun sendInput(bufferInfo: BufferInfo, message: String) = RPC(
+    "2sendInput(BufferInfo,QString)", ARG(bufferInfo, QType.BufferInfo),
+    ARG(message, Type.QString)
+  )
 
   inline fun RPC(function: String, vararg arg: QVariant_) {
     // Don’t transmit calls back that we just got from the network
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 42707bd16..4c924616d 100644
--- a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt
@@ -20,7 +20,8 @@ class Session(
   address: SocketAddress,
   private val handlerService: HandlerService,
   backlogStorage: BacklogStorage,
-  private var userData: Pair<String, String>
+  private var userData: Pair<String, String>,
+  val disconnectFromCore: () -> Unit
 ) : ProtocolHandler(), ISession {
   override val features = Features(clientData.clientFeatures, Quassel_Features.of())
 
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 48518bd1e..b252dc121 100644
--- a/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt
@@ -16,9 +16,12 @@ import io.reactivex.subjects.BehaviorSubject
 import javax.net.ssl.SSLSession
 import javax.net.ssl.X509TrustManager
 
-class SessionManager(offlineSession: ISession,
-                     val backlogStorage: BacklogStorage,
-                     val handlerService: HandlerService) : ISession {
+class SessionManager(
+  offlineSession: ISession,
+  val backlogStorage: BacklogStorage,
+  val handlerService: HandlerService,
+  private val disconnectFromCore: () -> Unit
+) : ISession {
   override val features: Features
     get() = session.or(lastSession).features
   override val sslSession: SSLSession?
@@ -121,7 +124,8 @@ class SessionManager(offlineSession: ISession,
         address,
         handlerService,
         backlogStorage,
-        userData
+        userData,
+        disconnectFromCore
       )
     )
   }
diff --git a/lib/src/test/java/de/kuschku/libquassel/ConnectionUnitTest.kt b/lib/src/test/java/de/kuschku/libquassel/ConnectionUnitTest.kt
index 1bdc88b92..53cbe7359 100644
--- a/lib/src/test/java/de/kuschku/libquassel/ConnectionUnitTest.kt
+++ b/lib/src/test/java/de/kuschku/libquassel/ConnectionUnitTest.kt
@@ -36,8 +36,8 @@ class ConnectionUnitTest {
         buildDate = Instant.EPOCH,
         clientFeatures = Quassel_Feature.of(*QuasselFeature.validValues),
         protocolFeatures = Protocol_Feature.of(ProtocolFeature.TLS, ProtocolFeature.Compression),
-        supportedProtocols = listOf(Protocol.Datastream)
-      ), object : X509TrustManager {
+        supportedProtocols = listOf(Protocol.Datastream),
+        ), object : X509TrustManager {
       override fun checkClientTrusted(p0: Array<out X509Certificate>?, p1: String?) {
       }
 
@@ -51,8 +51,8 @@ class ConnectionUnitTest {
       override fun clearMessages(bufferId: BufferId, idRange: IntRange) = Unit
       override fun clearMessages(bufferId: BufferId) = Unit
       override fun clearMessages() = Unit
-    }, user to pass
-    )
+    }, user to pass,
+      ) {}
     session.join()
   }
 }
-- 
GitLab