Refactor duplicated code patterns in rotation providers, sinks, and protocol tests
Found and eliminated ~240 lines of duplicated code across rotation providers, network sinks, and integration tests.
Changes
Rotation Providers
Extracted common listener management pattern from DisplayRotationProvider and SensorRotationProvider into base RotationProvider:
abstract class RotationProvider : IRotationProvider {
protected val lock = Any()
protected open fun onFirstListenerAdded() {}
protected open fun onLastListenerRemoved() {}
protected fun notifyListeners(@RotationValue rotation: Int) { ... }
}
Subclasses now override hooks instead of reimplementing listener lifecycle and synchronization.
Network Sinks
Created AbstractStatefulSink for common state management in RtmpSink and SrtSink:
-
isOpenFlow: StateFlow<Boolean> -
isOnError: Boolean
Protocol Tests
Extracted 95% identical test logic from RtmpSingleStreamerTest and SrtSingleStreamerTest into ProtocolStreamerTestHelper:
ProtocolStreamerTestHelper.runProtocolStreamingTest(
context, apiKey, "RTMP",
streamUrlBuilder = { key -> "rtmps://broadcast.api.video:1936/s/$key" },
tag = TAG
)
Protocol-specific URL formatting is now the only difference between tests (was 133 lines per test, now 50).
Impact
- 9 files changed: +224/-239 lines
- No breaking changes to public APIs
- Backward compatible with existing sinks extending
AbstractSink
[!WARNING]
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
dl.google.com
- Triggering command:
/usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED -Xmx2048m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.13-bin/5xuhj0ry160q40clulazy9h7d/gradle-8.13/lib/gradle-daemon-main-8.13.jar -javaagent:/home/REDACTED/.gradle/wrapper/dists/gradle-8.13-bin/5xuhj0ry160q40clulazy9h7d/gradle-8.13/lib/agents/gradle-instrumentation-agent-8.13.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.13(dns block)If you need me to access, download, or install something from one of these locations, you can either:
- Configure Actions setup steps to set up my environment, which run before the firewall is enabled
- Add the appropriate URLs or hosts to the custom allowlist in this repository's Copilot coding agent settings (admins only)
Original prompt
Find and refactor duplicated code
ð¬ We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.