Browse Source

Check preview RPC protocol version (#907)

Show notification, when preview client and server use different versions
of the protocol
pull/909/head
Alexey Tsvetkov 4 years ago committed by GitHub
parent
commit
c271999ec8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      gradle-plugins/preview-rpc/src/main/kotlin/org/jetbrains/compose/desktop/ui/tooling/preview/rpc/PreviewListener.kt
  2. 2
      gradle-plugins/preview-rpc/src/main/kotlin/org/jetbrains/compose/desktop/ui/tooling/preview/rpc/PreviewManager.kt
  3. 13
      gradle-plugins/preview-rpc/src/main/kotlin/org/jetbrains/compose/desktop/ui/tooling/preview/rpc/commands.kt
  4. 8
      gradle-plugins/preview-rpc/src/main/kotlin/org/jetbrains/compose/desktop/ui/tooling/preview/rpc/protocolVersion.kt
  5. 21
      idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewStateService.kt
  6. 2
      idea-plugin/src/main/resources/META-INF/plugin.xml

7
gradle-plugins/preview-rpc/src/main/kotlin/org/jetbrains/compose/desktop/ui/tooling/preview/rpc/PreviewListener.kt

@ -10,6 +10,7 @@ interface PreviewListener {
fun onFinishedBuild(success: Boolean) fun onFinishedBuild(success: Boolean)
fun onNewRenderRequest(previewRequest: FrameRequest) fun onNewRenderRequest(previewRequest: FrameRequest)
fun onRenderedFrame(frame: RenderedFrame) fun onRenderedFrame(frame: RenderedFrame)
fun onIncompatibleProtocolVersions(versionServer: Int, versionClient: Int)
} }
open class PreviewListenerBase : PreviewListener { open class PreviewListenerBase : PreviewListener {
@ -18,6 +19,8 @@ open class PreviewListenerBase : PreviewListener {
override fun onNewRenderRequest(previewRequest: FrameRequest) {} override fun onNewRenderRequest(previewRequest: FrameRequest) {}
override fun onRenderedFrame(frame: RenderedFrame) {} override fun onRenderedFrame(frame: RenderedFrame) {}
override fun onIncompatibleProtocolVersions(versionServer: Int, versionClient: Int) {}
} }
class CompositePreviewListener : PreviewListener { class CompositePreviewListener : PreviewListener {
@ -39,6 +42,10 @@ class CompositePreviewListener : PreviewListener {
forEachListener { it.onRenderedFrame(frame) } forEachListener { it.onRenderedFrame(frame) }
} }
override fun onIncompatibleProtocolVersions(versionServer: Int, versionClient: Int) {
forEachListener { it.onIncompatibleProtocolVersions(versionServer, versionClient) }
}
@Synchronized @Synchronized
fun addListener(listener: PreviewListener) { fun addListener(listener: PreviewListener) {
listeners.add(listener) listeners.add(listener)

2
gradle-plugins/preview-rpc/src/main/kotlin/org/jetbrains/compose/desktop/ui/tooling/preview/rpc/PreviewManager.kt

@ -88,7 +88,7 @@ class PreviewManagerImpl(
if (previewConfig != null && runningPreview?.isAlive != true) { if (previewConfig != null && runningPreview?.isAlive != true) {
val process = startPreviewProcess(previewConfig) val process = startPreviewProcess(previewConfig)
val connection = tryAcceptConnection(previewSocket, "PREVIEW") val connection = tryAcceptConnection(previewSocket, "PREVIEW")
connection?.receiveAttach { connection?.receiveAttach(listener = previewListener) {
this.runningPreview.set(RunningPreview(connection, process)) this.runningPreview.set(RunningPreview(connection, process))
} }
} }

13
gradle-plugins/preview-rpc/src/main/kotlin/org/jetbrains/compose/desktop/ui/tooling/preview/rpc/commands.kt

@ -9,12 +9,19 @@ import java.net.URLDecoder
import java.net.URLEncoder import java.net.URLEncoder
internal fun RemoteConnection.sendAttach() { internal fun RemoteConnection.sendAttach() {
sendCommand(Command.Type.ATTACH) sendCommand(Command.Type.ATTACH, PROTOCOL_VERSION.toString())
} }
internal fun RemoteConnection.receiveAttach(fn: () -> Unit) { internal fun RemoteConnection.receiveAttach(
receiveCommand { (type, _) -> listener: PreviewListener? = null,
fn: () -> Unit
) {
receiveCommand { (type, args) ->
if (type == Command.Type.ATTACH) { if (type == Command.Type.ATTACH) {
val version = args.firstOrNull()?.toIntOrNull() ?: 0
if (PROTOCOL_VERSION != version) {
listener?.onIncompatibleProtocolVersions(PROTOCOL_VERSION, version)
}
fn() fn()
} }
} }

8
gradle-plugins/preview-rpc/src/main/kotlin/org/jetbrains/compose/desktop/ui/tooling/preview/rpc/protocolVersion.kt

@ -0,0 +1,8 @@
/*
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file.
*/
package org.jetbrains.compose.desktop.ui.tooling.preview.rpc
const val PROTOCOL_VERSION = 1

21
idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewStateService.kt

@ -5,18 +5,20 @@
package org.jetbrains.compose.desktop.ide.preview package org.jetbrains.compose.desktop.ide.preview
import com.intellij.notification.NotificationGroupManager
import com.intellij.notification.NotificationType
import com.intellij.openapi.Disposable import com.intellij.openapi.Disposable
import com.intellij.openapi.components.Service import com.intellij.openapi.components.Service
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.Disposer
import com.intellij.ui.components.JBLoadingPanel import com.intellij.ui.components.JBLoadingPanel
import org.jetbrains.compose.desktop.ui.tooling.preview.rpc.* import org.jetbrains.compose.desktop.ui.tooling.preview.rpc.*
import java.awt.Dimension
import javax.swing.JComponent import javax.swing.JComponent
import javax.swing.event.AncestorEvent import javax.swing.event.AncestorEvent
import javax.swing.event.AncestorListener import javax.swing.event.AncestorListener
@Service @Service
class PreviewStateService : Disposable { class PreviewStateService(private val myProject: Project) : Disposable {
private val previewListener = CompositePreviewListener() private val previewListener = CompositePreviewListener()
private val previewManager: PreviewManager = PreviewManagerImpl(previewListener) private val previewManager: PreviewManager = PreviewManagerImpl(previewListener)
val gradleCallbackPort: Int val gradleCallbackPort: Int
@ -36,6 +38,21 @@ class PreviewStateService : Disposable {
previewListener.addListener(PreviewPanelUpdater(previewPanel)) previewListener.addListener(PreviewPanelUpdater(previewPanel))
previewListener.addListener(LoadingPanelUpdater(loadingPanel)) previewListener.addListener(LoadingPanelUpdater(loadingPanel))
previewListener.addListener(object : PreviewListenerBase() {
private val reported = hashSetOf<Pair<Int, Int>>()
override fun onIncompatibleProtocolVersions(versionServer: Int, versionClient: Int) {
if (reported.add(versionServer to versionClient)) {
NotificationGroupManager.getInstance()
.getNotificationGroup("Compose MPP Notifications")
.createNotification("Compose Desktop Preview may be incompatible " +
"with provided Compose Gradle plugin. " +
"Please use matching versions.",
NotificationType.ERROR)
.notify(myProject)
}
}
})
} }
internal fun buildStarted() { internal fun buildStarted() {

2
idea-plugin/src/main/resources/META-INF/plugin.xml

@ -38,5 +38,7 @@
anchor="right" /> anchor="right" />
<lang.inspectionSuppressor language="kotlin" implementationClass="org.jetbrains.compose.inspections.ComposeSuppressor"/> <lang.inspectionSuppressor language="kotlin" implementationClass="org.jetbrains.compose.inspections.ComposeSuppressor"/>
<notificationGroup id="Compose MPP Notifications" displayType="BALLOON"/>
</extensions> </extensions>
</idea-plugin> </idea-plugin>

Loading…
Cancel
Save