From 956f8c28f2ae3631d6495b312bf10671a3f2ba10 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sat, 14 Feb 2026 14:24:22 +0000 Subject: [PATCH 01/50] chore(deps): use kotlin for dokka deps --- gradle/libs.versions.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a46077215..a1fbbf983 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ junit4 = "4.13.2" junit5 = "5.10.1" junit5commons = "1.10.1" imageComparison = "4.4.0" -dokka = "1.9.10" + grpc = "1.59.0" grpcKotlin = "1.4.0" grpcOkhttp = "1.59.0" @@ -56,14 +56,14 @@ image-comparison = { module = "com.github.romankh3:image-comparison", version.re ## Gradle Plugins kotlin-gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } androidx-gradle = { module = "com.android.tools.build:gradle", version.ref = "androidGradle" } -dokka-gradle = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "dokka" } +dokka-gradle = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "kotlin" } spotless-gradle = { group = "com.diffplug.spotless", name = "spotless-plugin-gradle", version.ref = "spotless" } ktlint-core = { module = "com.pinterest.ktlint:ktlint-cli", version.ref = "ktlint-core" } [plugins] kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } -dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } +dokka = { id = "org.jetbrains.dokka", version.ref = "kotlin" } protobuf = { id = "com.google.protobuf", version.ref = "protobufGradle" } android-library = { id = "com.android.library", version.ref = "androidGradle" } gradle-versions = { id = "com.github.ben-manes.versions", version.ref = "gradleVersionsPlugin" } From 37d0482311a0d6e743a9df9248fae2b4c94b1254 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sat, 14 Feb 2026 15:14:25 +0000 Subject: [PATCH 02/50] feat: WIP updating project --- .../adam/integration/PortForwardE2ETest.kt | 4 +- .../com/malinskiy/adam/log/AdamLogging.kt | 4 +- .../vertx/VariableSizeRecordParser.kt | 14 ++-- .../adam/transport/vertx/VertxSocket.kt | 16 ++--- .../transport/vertx/VertxSocketFactory.kt | 4 +- .../framebuffer/ScreenCaptureRequestTest.kt | 1 - .../CreateMultiPackageSessionRequestTest.kt | 8 +-- .../request/sync/v1/PullFileRequestTest.kt | 2 +- .../request/sync/v2/PullFileRequestTest.kt | 2 +- .../adam/junit4/android/rule/AdbRule.kt | 1 + .../AdamScreenCaptureProcessor.kt | 2 + .../screencapture/AdamScreenCaptureRule.kt | 2 + gradle/libs.versions.toml | 43 ++++++------ .../adam/server/junit5/AdbServerExtension.kt | 2 +- .../server/stub/AndroidDebugBridgeServer.kt | 14 ++-- .../adam/server/stub/ConsoleReadChannel.kt | 4 +- .../adam/server/stub/EmulatorConsoleServer.kt | 7 +- .../adam/server/stub/ServerReadChannel.kt | 19 ++++-- .../adam/server/stub/ServerWriteChannel.kt | 45 +++++++++---- .../malinskiy/adam/server/stub/StubSocket.kt | 61 ++++++++++++----- .../malinskiy/adam/server/stub/dsl/Session.kt | 1 - .../adam/transport/ktor/KtorSocket.kt | 67 ++++++++++++++----- .../adam/transport/ktor/KtorSocketFactory.kt | 3 +- 23 files changed, 207 insertions(+), 119 deletions(-) diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PortForwardE2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PortForwardE2ETest.kt index dcf342ccc..41ed8eb2f 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PortForwardE2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PortForwardE2ETest.kt @@ -107,7 +107,7 @@ class PortForwardE2ETest { ) assertThat(portString).isNotNull() - val actual = portString!!.toInt() + val actual = portString!! val expected = (currentPortForwards.firstOrNull()?.localSpec as LocalTcpPortSpec).port assertThat(actual).isEqualTo(expected) @@ -175,7 +175,7 @@ class PortForwardE2ETest { if (portString != null) { //Some devices return the allocated port - val actual = portString.toInt() + val actual = portString val expected = (currentPortForwards.firstOrNull()?.localSpec as RemoteTcpPortSpec).port assertThat(actual).isEqualTo(expected) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/log/AdamLogging.kt b/adam/src/main/kotlin/com/malinskiy/adam/log/AdamLogging.kt index b1af01c5c..36eb08fc2 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/log/AdamLogging.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/log/AdamLogging.kt @@ -16,8 +16,8 @@ package com.malinskiy.adam.log -import mu.KLogger -import mu.KotlinLogging +import io.github.oshai.kotlinlogging.KLogger +import io.github.oshai.kotlinlogging.KotlinLogging object AdamLogging { fun logger(func: () -> Unit): KLogger = KotlinLogging.logger(func) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VariableSizeRecordParser.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VariableSizeRecordParser.kt index 971afd112..c9ec118a7 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VariableSizeRecordParser.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VariableSizeRecordParser.kt @@ -16,10 +16,8 @@ package com.malinskiy.adam.transport.vertx -import io.netty.buffer.Unpooled import io.vertx.core.Handler import io.vertx.core.buffer.Buffer -import io.vertx.core.impl.Arguments import io.vertx.core.streams.ReadStream import kotlin.math.min @@ -27,9 +25,9 @@ class VariableSizeRecordParser( private val stream: ReadStream? = null ) : Handler, ReadStream { // Empty and unmodifiable - private val EMPTY_BUFFER = Buffer.buffer(Unpooled.EMPTY_BUFFER) - private var buff = EMPTY_BUFFER - private val bufferLock = Object() + private val EMPTY_BUFFER: Buffer = Buffer.buffer() + private var buff: Buffer = EMPTY_BUFFER + private val bufferLock = Any() private var pos = 0 // Current position in buffer private var start = 0 // Position of beginning of current record private var requestedAtMost = 0 @@ -40,7 +38,7 @@ class VariableSizeRecordParser( private var exceptionHandler: Handler? = null private var streamEnded = false private val drained - get() = streamEnded && (buff.byteBuf.writerIndex() == 0) + get() = streamEnded && (buff.length() == 0) /** * This method is called to provide the parser with data.toChannel @@ -63,7 +61,7 @@ class VariableSizeRecordParser( } fun request(size: Int) { - Arguments.require(size > 0, "Size must be > 0") + require(size > 0) { "Size must be > 0" } requestedAtMost = size handleParsing() } @@ -161,7 +159,7 @@ class VariableSizeRecordParser( override fun pause() = apply { demand = 0L } override fun fetch(amount: Long): ReadStream { - Arguments.require(amount > 0, "Fetch amount must be > 0") + require(amount > 0) { "Fetch amount must be > 0" } demand += amount if (demand < 0L) { demand = Long.MAX_VALUE diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocket.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocket.kt index f5a0909e9..e492fe65d 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocket.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocket.kt @@ -32,7 +32,7 @@ import io.vertx.core.net.SocketAddress import io.vertx.core.net.impl.NetSocketImpl import io.vertx.core.streams.ReadStream import io.vertx.kotlin.coroutines.CoroutineVerticle -import io.vertx.kotlin.coroutines.await +import io.vertx.kotlin.coroutines.coAwait import io.vertx.kotlin.coroutines.dispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.Channel @@ -60,7 +60,7 @@ class VertxSocket(private val socketAddress: SocketAddress, private val options: netClient = client val connect = client.connect(socketAddress) state.change(State.CREATED, State.SYN_SENT) { "Socket connection error" } - socket = connect.await() as NetSocketImpl + socket = connect.coAwait() as NetSocketImpl state.change(State.SYN_SENT, State.ESTABLISHED) { "Socket connection error" } canRead.flip(false) { "Socket connection error: canRead was true, expected false" } @@ -95,18 +95,18 @@ class VertxSocket(private val socketAddress: SocketAddress, private val options: override suspend fun writeFully(byteBuffer: ByteBuffer) { if (isClosedForWrite) throw IllegalStateException("Socket write error: socket is not connected ${state.get()}") val appendBytes = Buffer.buffer().appendBytes(byteBuffer.array(), byteBuffer.position(), byteBuffer.remaining()) - socket.write(appendBytes).await() + socket.write(appendBytes).coAwait() } suspend fun writeFully(buffer: Buffer) { if (isClosedForWrite) throw IllegalStateException("Socket write error: socket is not connected ${state.get()}") - socket.write(buffer).await() + socket.write(buffer).coAwait() } override suspend fun writeFully(byteArray: ByteArray, offset: Int, limit: Int) { if (isClosedForWrite) throw IllegalStateException("Socket write error: socket is not connected ${state.get()}") val appendBytes = Buffer.buffer().appendBytes(byteArray, offset, limit) - socket.write(appendBytes).await() + socket.write(appendBytes).coAwait() } override suspend fun readAvailable(buffer: ByteArray, offset: Int, limit: Int): Int { @@ -115,7 +115,7 @@ class VertxSocket(private val socketAddress: SocketAddress, private val options: recordParser.request(limit) } return readChannel.receiveCatching().getOrNull()?.let { - val actualLimit = it.byteBuf.writerIndex() + val actualLimit = it.length() assert(actualLimit <= limit) { "Received ${it.length()} more than we can chew $limit" } it.getBytes(0, actualLimit, buffer, offset) actualLimit @@ -181,7 +181,7 @@ class VertxSocket(private val socketAddress: SocketAddress, private val options: } override suspend fun close() { - socket.close().await() + socket.close().coAwait() /** * This should be maximum buffer that could've been requested in case: * 1. Read request for up to max initiated @@ -195,7 +195,7 @@ class VertxSocket(private val socketAddress: SocketAddress, private val options: } } id?.let { - vertx.undeploy(it).await() + vertx.undeploy(it).coAwait() } } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocketFactory.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocketFactory.kt index 4f0aa0292..c821dc9e9 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocketFactory.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocketFactory.kt @@ -21,7 +21,7 @@ import com.malinskiy.adam.transport.SocketFactory import io.vertx.core.Vertx import io.vertx.core.net.NetClientOptions import io.vertx.core.net.SocketAddress -import io.vertx.kotlin.coroutines.await +import io.vertx.kotlin.coroutines.coAwait import java.net.InetSocketAddress import java.util.concurrent.atomic.AtomicBoolean @@ -39,7 +39,7 @@ class VertxSocketFactory( setConnectTimeout((connectTimeout ?: this@VertxSocketFactory.connectTimeout).toTimeoutInt()) setIdleTimeout((idleTimeout ?: this@VertxSocketFactory.idleTimeout).toTimeoutInt()) }) - val id = vertx.deployVerticle(vertxSocket).await() + val id = vertx.deployVerticle(vertxSocket).coAwait() vertxSocket.id = id return vertxSocket } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequestTest.kt index 1a812510c..3f7d47a43 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequestTest.kt @@ -25,7 +25,6 @@ import com.malinskiy.adam.AndroidDebugBridgeClient import com.malinskiy.adam.exception.UnsupportedImageProtocolException import com.malinskiy.adam.extension.newFileWithExtension import com.malinskiy.adam.server.junit4.AdbServerRule -import io.ktor.utils.io.writeIntLittleEndian import kotlinx.coroutines.runBlocking import org.junit.Rule import org.junit.Test diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/CreateMultiPackageSessionRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/CreateMultiPackageSessionRequestTest.kt index dcb3eb783..679104d48 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/CreateMultiPackageSessionRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/CreateMultiPackageSessionRequestTest.kt @@ -28,9 +28,7 @@ import com.malinskiy.adam.request.Feature import com.malinskiy.adam.request.ValidationResponse import com.malinskiy.adam.server.stub.StubSocket import com.malinskiy.adam.transport.use -import io.ktor.utils.io.ByteChannelSequentialJVM -import io.ktor.utils.io.ByteWriteChannel -import io.ktor.utils.io.core.internal.ChunkBuffer + import kotlinx.coroutines.runBlocking import org.junit.Rule import org.junit.Test @@ -105,7 +103,6 @@ class CreateMultiPackageSessionRequestTest { fun testRead() { val request = stub() val response = "Success [my-session-id]".toByteArray(Const.DEFAULT_TRANSPORT_ENCODING) - val byteBufferChannel: ByteWriteChannel = ByteChannelSequentialJVM(ChunkBuffer.Empty, false) runBlocking { StubSocket(response).use { socket -> val (sessionId, output) = request.readElement(socket) @@ -119,7 +116,6 @@ class CreateMultiPackageSessionRequestTest { fun testReadException() { val request = stub() val response = "Failure".toByteArray(Const.DEFAULT_TRANSPORT_ENCODING) - val byteBufferChannel: ByteWriteChannel = ByteChannelSequentialJVM(ChunkBuffer.Empty, false) runBlocking { StubSocket(response).use { socket -> request.readElement(socket) @@ -232,7 +228,7 @@ class CreateMultiPackageSessionRequestTest { @Test fun testValidationFailureApkSplit() { - val pkg = ApkSplitInstallationPackage(listOf(temp.newFileWithExtension("apk"), createTempFile(suffix = ".app"))) + val pkg = ApkSplitInstallationPackage(listOf(temp.newFileWithExtension("apk"), kotlin.io.path.createTempFile(suffix = ".app").toFile())) var request = CreateMultiPackageSessionRequest( supportedFeatures = listOf(Feature.CMD), extraArgs = emptyList(), diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/PullFileRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/PullFileRequestTest.kt index beaf7e4ce..10664944b 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/PullFileRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/PullFileRequestTest.kt @@ -24,7 +24,7 @@ import com.malinskiy.adam.exception.PullFailedException import com.malinskiy.adam.exception.UnsupportedSyncProtocolException import com.malinskiy.adam.server.junit4.AdbServerRule import io.ktor.utils.io.discard -import io.ktor.utils.io.writeIntLittleEndian + import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.junit.Rule diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/PullFileRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/PullFileRequestTest.kt index 216dce597..c33f212fe 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/PullFileRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/PullFileRequestTest.kt @@ -25,7 +25,7 @@ import com.malinskiy.adam.exception.UnsupportedSyncProtocolException import com.malinskiy.adam.request.Feature import com.malinskiy.adam.server.junit4.AdbServerRule import io.ktor.utils.io.discard -import io.ktor.utils.io.writeIntLittleEndian + import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.junit.Rule diff --git a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/AdbRule.kt b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/AdbRule.kt index ff0402d55..58013fcc1 100644 --- a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/AdbRule.kt +++ b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/AdbRule.kt @@ -34,6 +34,7 @@ import kotlin.coroutines.CoroutineContext /** * @param coroutineContext it's your responsibility to cancel this context when needed */ +@OptIn(UnsafeAdbAccess::class) class AdbRule(private val mode: Mode = Mode.ASSERT, private val coroutineContext: CoroutineContext = Dispatchers.IO) : TestRule { lateinit var adb: SingleTargetAndroidDebugBridgeClient diff --git a/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureProcessor.kt b/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureProcessor.kt index c03360c34..33f9d857e 100644 --- a/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureProcessor.kt +++ b/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureProcessor.kt @@ -14,6 +14,8 @@ * limitations under the License. */ +@file:Suppress("DEPRECATION") + package com.malinskiy.adam.junit4.android.screencapture import android.os.Bundle diff --git a/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureRule.kt b/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureRule.kt index 86efa2a34..b09ba5ef8 100644 --- a/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureRule.kt +++ b/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureRule.kt @@ -14,6 +14,8 @@ * limitations under the License. */ +@file:Suppress("DEPRECATION") + package com.malinskiy.adam.junit4.android.screencapture import androidx.test.runner.screenshot.Screenshot diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a1fbbf983..b20d206bd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,28 +1,29 @@ [versions] adam = "0.5.7" -kotlin = "1.9.10" -coroutines = "1.7.3" -annotations = "24.0.1" -ktor = "2.3.6" -logging = "3.0.5" -vertx = "4.4.6" -apacheCommonsPool2 = "2.11.1" -assertk = "0.27.0" +kotlin = "2.3.10" +coroutines = "1.10.2" +annotations = "26.0.2" +ktor = "3.4.0" +logging = "7.0.14" +vertx = "5.0.7" +apacheCommonsPool2 = "2.13.1" +assertk = "0.28.1" junit4 = "4.13.2" -junit5 = "5.10.1" -junit5commons = "1.10.1" +junit5 = "6.0.2" +junit5commons = "6.0.2" imageComparison = "4.4.0" -grpc = "1.59.0" -grpcKotlin = "1.4.0" -grpcOkhttp = "1.59.0" -protobufGradle = "0.9.4" -protobuf = "3.25.0" +grpc = "1.79.0" +grpcKotlin = "1.5.0" +grpcOkhttp = "1.79.0" +protobufGradle = "0.9.6" +protobuf = "4.33.5" javax = "1.3.2" androidGradle = "9.0.0" -testMonitor = "1.6.1" -testRunner = "1.5.2" -gradleVersionsPlugin = "0.49.0" +testMonitor = "1.8.0" +testRunner = "1.7.0" +gradleVersionsPlugin = "0.53.0" +dokka = "2.1.0" spotless = "8.2.1" ktlint-core = "1.8.0" @@ -35,7 +36,7 @@ apache-commons-pool2 = { module = "org.apache.commons:commons-pool2", version.re coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } coroutines-debug = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-debug", version.ref = "coroutines" } ktor-network = { module = "io.ktor:ktor-network-jvm", version.ref = "ktor" } -logging = { module = "io.github.microutils:kotlin-logging", version.ref = "logging" } +logging = { module = "io.github.oshai:kotlin-logging", version.ref = "logging" } vertx-core = { module = "io.vertx:vertx-core", version.ref = "vertx" } vertx-kotlin = { module = "io.vertx:vertx-lang-kotlin", version.ref = "vertx" } vertx-coroutines = { module = "io.vertx:vertx-lang-kotlin-coroutines", version.ref = "vertx" } @@ -56,14 +57,14 @@ image-comparison = { module = "com.github.romankh3:image-comparison", version.re ## Gradle Plugins kotlin-gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } androidx-gradle = { module = "com.android.tools.build:gradle", version.ref = "androidGradle" } -dokka-gradle = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "kotlin" } +dokka-gradle = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "dokka" } spotless-gradle = { group = "com.diffplug.spotless", name = "spotless-plugin-gradle", version.ref = "spotless" } ktlint-core = { module = "com.pinterest.ktlint:ktlint-cli", version.ref = "ktlint-core" } [plugins] kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } -dokka = { id = "org.jetbrains.dokka", version.ref = "kotlin" } +dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } protobuf = { id = "com.google.protobuf", version.ref = "protobufGradle" } android-library = { id = "com.android.library", version.ref = "androidGradle" } gradle-versions = { id = "com.github.ben-manes.versions", version.ref = "gradleVersionsPlugin" } diff --git a/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbServerExtension.kt b/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbServerExtension.kt index 85f0b19b0..40900ef1a 100644 --- a/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbServerExtension.kt +++ b/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbServerExtension.kt @@ -72,7 +72,7 @@ class AdbServerExtension : BeforeEachCallback, AfterEachCallback { } } - override fun afterEach(context: ExtensionContext?) { + override fun afterEach(context: ExtensionContext) { runBlocking { withContext(NonCancellable) { server.dispose() diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/AndroidDebugBridgeServer.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/AndroidDebugBridgeServer.kt index b3c8497c0..022a41432 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/AndroidDebugBridgeServer.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/AndroidDebugBridgeServer.kt @@ -20,7 +20,7 @@ import com.malinskiy.adam.AndroidDebugBridgeClient import com.malinskiy.adam.AndroidDebugBridgeClientFactory import com.malinskiy.adam.server.stub.dsl.Expectation import com.malinskiy.adam.server.stub.dsl.Session -import io.ktor.network.selector.ActorSelectorManager +import io.ktor.network.selector.SelectorManager import io.ktor.network.sockets.InetSocketAddress import io.ktor.network.sockets.ServerSocket import io.ktor.network.sockets.aSocket @@ -30,7 +30,6 @@ import io.ktor.network.sockets.toJavaAddress import io.ktor.util.network.port import io.ktor.utils.io.ByteReadChannel import io.ktor.utils.io.ByteWriteChannel -import io.ktor.utils.io.close import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob @@ -38,6 +37,7 @@ import kotlinx.coroutines.async import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.isActive import kotlinx.coroutines.newFixedThreadPoolContext +import kotlinx.coroutines.runBlocking import kotlin.coroutines.CoroutineContext @@ -58,12 +58,12 @@ class AndroidDebugBridgeServer : CoroutineScope { var port: Int = 0 lateinit var server: ServerSocket - lateinit var selector: ActorSelectorManager + lateinit var selector: SelectorManager fun start(): AndroidDebugBridgeClient { val address = InetSocketAddress("127.0.0.1", port) - selector = ActorSelectorManager(Dispatchers.IO) - server = aSocket(selector).tcp().bind(address) + selector = SelectorManager(Dispatchers.IO) + server = runBlocking { aSocket(selector).tcp().bind(address) } port = server.localAddress.toJavaAddress().port return client @@ -94,7 +94,7 @@ class AndroidDebugBridgeServer : CoroutineScope { } catch (e: Throwable) { e.printStackTrace() } finally { - output.close() + output.flushAndClose() socket.close() } } @@ -113,7 +113,7 @@ class AndroidDebugBridgeServer : CoroutineScope { } catch (e: Throwable) { e.printStackTrace() } finally { - output.close() + output.flushAndClose() socket.close() } } catch (e: Exception) { diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ConsoleReadChannel.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ConsoleReadChannel.kt index 6ddf4d21e..8fe5a52bc 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ConsoleReadChannel.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ConsoleReadChannel.kt @@ -20,10 +20,10 @@ import assertk.assertThat import assertk.assertions.isEqualTo import assertk.assertions.startsWith import io.ktor.utils.io.ByteReadChannel -import io.ktor.utils.io.readUTF8Line +import io.ktor.utils.io.readLine class ConsoleReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel by delegate { - suspend fun receiveCommand() = delegate.readUTF8Line()!! + suspend fun receiveCommand() = delegate.readLine()!! suspend fun receiveAuth() = receiveCommand().apply { assertThat(this).startsWith("auth ") }.substringAfter("auth ") suspend fun receiveExit() = receiveCommand().apply { assertThat(this).isEqualTo("quit") } } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/EmulatorConsoleServer.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/EmulatorConsoleServer.kt index 283359bcc..589e94196 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/EmulatorConsoleServer.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/EmulatorConsoleServer.kt @@ -18,7 +18,7 @@ package com.malinskiy.adam.server.stub import com.malinskiy.adam.AndroidDebugBridgeClient import com.malinskiy.adam.AndroidDebugBridgeClientFactory -import io.ktor.network.selector.ActorSelectorManager +import io.ktor.network.selector.SelectorManager import io.ktor.network.sockets.InetSocketAddress import io.ktor.network.sockets.aSocket import io.ktor.network.sockets.openReadChannel @@ -27,7 +27,6 @@ import io.ktor.network.sockets.toJavaAddress import io.ktor.util.network.port import io.ktor.utils.io.ByteReadChannel import io.ktor.utils.io.ByteWriteChannel -import io.ktor.utils.io.close import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob @@ -52,7 +51,7 @@ class EmulatorConsoleServer : CoroutineScope, Closeable { suspend fun startAndListen(block: suspend (ConsoleReadChannel, ConsoleWriteChannel) -> Unit): Pair { val address = InetSocketAddress("127.0.0.1", port) - val server = aSocket(ActorSelectorManager(Dispatchers.IO)).tcp().bind(address) + val server = aSocket(SelectorManager(Dispatchers.IO)).tcp().bind(address) port = server.localAddress.toJavaAddress().port async(context = job) { @@ -66,7 +65,7 @@ class EmulatorConsoleServer : CoroutineScope, Closeable { } catch (e: Throwable) { e.printStackTrace() } finally { - output.close() + output.flushAndClose() socket.close() } } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerReadChannel.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerReadChannel.kt index 3db344b91..9ffd491dc 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerReadChannel.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerReadChannel.kt @@ -25,13 +25,24 @@ import com.malinskiy.adam.request.shell.v2.MessageType import com.malinskiy.adam.request.sync.v2.CompressionType import io.ktor.util.cio.writeChannel import io.ktor.utils.io.ByteReadChannel -import io.ktor.utils.io.close -import io.ktor.utils.io.readIntLittleEndian +import io.ktor.utils.io.readByteArray +import io.ktor.utils.io.writeByteArray +import io.ktor.utils.io.readByte as channelReadByte +import io.ktor.utils.io.readInt as channelReadInt import kotlinx.coroutines.Job import java.io.File import kotlin.coroutines.coroutineContext class ServerReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel by delegate { + + suspend fun readByte(): Byte = delegate.channelReadByte() + + suspend fun readIntLittleEndian(): Int = Integer.reverseBytes(delegate.channelReadInt()) + + suspend fun readFully(dst: ByteArray, offset: Int, length: Int) { + val tmp = delegate.readByteArray(length) + System.arraycopy(tmp, 0, dst, offset, length) + } suspend fun receiveCommand(): String { val bytes = ByteArray(4) readFully(bytes, 0, 4) @@ -177,7 +188,7 @@ class ServerReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel when { header.contentEquals(Const.Message.DONE) -> { channel.flush() - channel.close() + channel.flushAndClose() return file } header.contentEquals(Const.Message.DATA) -> { @@ -186,7 +197,7 @@ class ServerReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel throw UnsupportedSyncProtocolException() } readFully(dataBuffer, 0, available) - channel.writeFully(dataBuffer, 0, available) + channel.writeByteArray(dataBuffer.copyOfRange(0, available)) } else -> throw RuntimeException("Something bad happened") } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerWriteChannel.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerWriteChannel.kt index 038a02556..33872afd0 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerWriteChannel.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerWriteChannel.kt @@ -19,17 +19,36 @@ package com.malinskiy.adam.server.stub import com.malinskiy.adam.Const import com.malinskiy.adam.request.shell.v2.MessageType import io.ktor.utils.io.ByteWriteChannel -import io.ktor.utils.io.writeByte -import io.ktor.utils.io.writeFully -import io.ktor.utils.io.writeIntLittleEndian -import io.ktor.utils.io.writeLongLittleEndian +import io.ktor.utils.io.writeByteArray import io.ktor.utils.io.writeStringUtf8 import java.nio.ByteBuffer +import io.ktor.utils.io.writeInt as channelWriteInt +import io.ktor.utils.io.writeLong as channelWriteLong +import io.ktor.utils.io.writeByte as channelWriteByte class ServerWriteChannel(private val delegate: ByteWriteChannel) : ByteWriteChannel by delegate { private suspend fun write(request: ByteArray, length: Int? = null) { - val requestBuffer = ByteBuffer.wrap(request, 0, length ?: request.size) - delegate.writeFully(requestBuffer) + delegate.writeByteArray(request.copyOfRange(0, length ?: request.size)) + } + + suspend fun writeIntLittleEndian(value: Int) { + delegate.channelWriteInt(Integer.reverseBytes(value)) + } + + private suspend fun writeLongLittleEndian(value: Long) { + delegate.channelWriteLong(java.lang.Long.reverseBytes(value)) + } + + suspend fun writeFully(src: ByteArray) { + delegate.writeByteArray(src) + } + + suspend fun writeFully(src: ByteArray, offset: Int, length: Int) { + delegate.writeByteArray(src.copyOfRange(offset, offset + length)) + } + + suspend fun writeByte(value: Byte) { + delegate.channelWriteByte(value) } suspend fun respond(request: ByteArray, length: Int? = null) = write(request, length) @@ -169,26 +188,26 @@ class ServerWriteChannel(private val delegate: ByteWriteChannel) : ByteWriteChan } suspend fun respondShellV2Exit(exitCode: Int) { - writeByte(MessageType.EXIT.toValue().toByte()) - writeInt(1) - writeByte(exitCode) + delegate.channelWriteByte(MessageType.EXIT.toValue().toByte()) + delegate.channelWriteInt(1) + delegate.channelWriteByte(exitCode.toByte()) } suspend fun respondShellV2Stderr(stderr: String) { - writeByte(MessageType.STDERR.toValue().toByte()) + delegate.channelWriteByte(MessageType.STDERR.toValue().toByte()) respondStringV2(stderr) } suspend fun respondShellV2Stdout(stdout: String) { - writeByte(MessageType.STDOUT.toValue().toByte()) + delegate.channelWriteByte(MessageType.STDOUT.toValue().toByte()) respondStringV2(stdout) } suspend fun respondShellV2WindowSizeChange() { - writeByte(MessageType.WINDOW_SIZE_CHANGE.toValue().toByte()) + delegate.channelWriteByte(MessageType.WINDOW_SIZE_CHANGE.toValue().toByte()) } suspend fun respondShellV2Invalid() { - writeByte(MessageType.INVALID.toValue().toByte()) + delegate.channelWriteByte(MessageType.INVALID.toValue().toByte()) } } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/StubSocket.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/StubSocket.kt index 4a8429d9a..e0785145e 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/StubSocket.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/StubSocket.kt @@ -17,20 +17,21 @@ package com.malinskiy.adam.server.stub import com.malinskiy.adam.transport.Socket -import io.ktor.utils.io.ByteChannelSequentialJVM +import io.ktor.utils.io.ByteChannel import io.ktor.utils.io.ByteReadChannel import io.ktor.utils.io.ByteWriteChannel import io.ktor.utils.io.cancel -import io.ktor.utils.io.close -import io.ktor.utils.io.core.internal.ChunkBuffer -import io.ktor.utils.io.readIntLittleEndian -import io.ktor.utils.io.writeByte -import io.ktor.utils.io.writeIntLittleEndian +import io.ktor.utils.io.readByteArray +import io.ktor.utils.io.readInt +import io.ktor.utils.io.writeByteArray +import io.ktor.utils.io.writeInt import java.nio.ByteBuffer +import io.ktor.utils.io.readByte as channelReadByte +import io.ktor.utils.io.writeByte as channelWriteByte class StubSocket( - val readChannel: ByteReadChannel = ByteChannelSequentialJVM(ChunkBuffer.Empty, false), - val writeChannel: ByteWriteChannel = ByteChannelSequentialJVM(ChunkBuffer.Empty, false) + val readChannel: ByteReadChannel = ByteChannel(false), + val writeChannel: ByteWriteChannel = ByteChannel(false) ) : Socket { override val isClosedForWrite: Boolean get() = writeChannel.isClosedForWrite @@ -39,19 +40,43 @@ class StubSocket( constructor(content: ByteArray) : this(readChannel = ByteReadChannel(content)) - override suspend fun readFully(buffer: ByteBuffer): Int = readChannel.readFully(buffer) - override suspend fun readFully(buffer: ByteArray, offset: Int, limit: Int) = readChannel.readFully(buffer, offset, limit) - override suspend fun writeFully(byteBuffer: ByteBuffer) = writeChannel.writeFully(byteBuffer) - override suspend fun writeFully(byteArray: ByteArray, offset: Int, limit: Int) = writeChannel.writeFully(byteArray, offset, limit) - override suspend fun readAvailable(buffer: ByteArray, offset: Int, limit: Int): Int = readChannel.readAvailable(buffer, offset, limit) - override suspend fun readByte(): Byte = readChannel.readByte() - override suspend fun readIntLittleEndian(): Int = readChannel.readIntLittleEndian() - override suspend fun writeByte(value: Int) = writeChannel.writeByte(value) - override suspend fun writeIntLittleEndian(value: Int) = writeChannel.writeIntLittleEndian(value) + override suspend fun readFully(buffer: ByteBuffer): Int { + val count = buffer.remaining() + val dst = readChannel.readByteArray(count) + buffer.put(dst) + return count + } + + override suspend fun readFully(buffer: ByteArray, offset: Int, limit: Int) { + val tmp = readChannel.readByteArray(limit) + System.arraycopy(tmp, 0, buffer, offset, limit) + } + + override suspend fun writeFully(byteBuffer: ByteBuffer) { + val src = ByteArray(byteBuffer.remaining()) + byteBuffer.get(src) + writeChannel.writeByteArray(src) + } + + override suspend fun writeFully(byteArray: ByteArray, offset: Int, limit: Int) { + writeChannel.writeByteArray(byteArray.copyOfRange(offset, offset + limit)) + } + + override suspend fun readAvailable(buffer: ByteArray, offset: Int, limit: Int): Int { + if (readChannel.isClosedForRead) return -1 + val tmp = readChannel.readByteArray(limit.coerceAtMost(1)) + System.arraycopy(tmp, 0, buffer, offset, tmp.size) + return tmp.size + } + + override suspend fun readByte(): Byte = readChannel.channelReadByte() + override suspend fun readIntLittleEndian(): Int = Integer.reverseBytes(readChannel.readInt()) + override suspend fun writeByte(value: Int) = writeChannel.channelWriteByte(value.toByte()) + override suspend fun writeIntLittleEndian(value: Int) = writeChannel.writeInt(Integer.reverseBytes(value)) override suspend fun close() { try { - writeChannel.close() + writeChannel.flushAndClose() readChannel.cancel() } catch (e: Exception) { println("Exception during cleanup. Ignoring") diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Session.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Session.kt index 91ca6b23a..8df1f9d08 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Session.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Session.kt @@ -21,7 +21,6 @@ import assertk.assertions.isEqualTo import com.malinskiy.adam.Const import com.malinskiy.adam.server.stub.ServerReadChannel import com.malinskiy.adam.server.stub.ServerWriteChannel -import io.ktor.utils.io.writeIntLittleEndian import java.io.File diff --git a/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocket.kt b/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocket.kt index 90f2f62b2..f6a1ad1bf 100644 --- a/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocket.kt +++ b/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocket.kt @@ -22,13 +22,16 @@ import io.ktor.network.sockets.openReadChannel import io.ktor.network.sockets.openWriteChannel import io.ktor.utils.io.ByteReadChannel import io.ktor.utils.io.ByteWriteChannel +import io.ktor.utils.io.availableForRead import io.ktor.utils.io.cancel -import io.ktor.utils.io.close -import io.ktor.utils.io.readIntLittleEndian -import io.ktor.utils.io.writeByte -import io.ktor.utils.io.writeIntLittleEndian +import io.ktor.utils.io.readByteArray +import io.ktor.utils.io.readInt +import io.ktor.utils.io.writeByteArray +import io.ktor.utils.io.writeInt import java.nio.ByteBuffer import io.ktor.network.sockets.Socket as RealKtorSocket +import io.ktor.utils.io.readByte as ktorReadByte +import io.ktor.utils.io.writeByte as ktorWriteByte class KtorSocket(private val ktorSocket: RealKtorSocket) : Socket { private val readChannel: ByteReadChannel = ktorSocket.openReadChannel() @@ -38,23 +41,57 @@ class KtorSocket(private val ktorSocket: RealKtorSocket) : Socket { override val isClosedForRead: Boolean get() = readChannel.isClosedForRead - override suspend fun readFully(buffer: ByteBuffer): Int = readChannel.readFully(buffer) - override suspend fun readFully(buffer: ByteArray, offset: Int, limit: Int) = readChannel.readFully(buffer, offset, limit) - override suspend fun writeFully(byteBuffer: ByteBuffer) = writeChannel.writeFully(byteBuffer) - override suspend fun writeFully(byteArray: ByteArray, offset: Int, limit: Int) = writeChannel.writeFully(byteArray, offset, limit) + override suspend fun readFully(buffer: ByteBuffer): Int { + val count = buffer.remaining() + val dst = readChannel.readByteArray(count) + buffer.put(dst) + return count + } + + override suspend fun readFully(buffer: ByteArray, offset: Int, limit: Int) { + val tmp = readChannel.readByteArray(limit) + System.arraycopy(tmp, 0, buffer, offset, limit) + } + + override suspend fun writeFully(byteBuffer: ByteBuffer) { + val src = ByteArray(byteBuffer.remaining()) + byteBuffer.get(src) + writeChannel.writeByteArray(src) + writeChannel.flush() + } + + override suspend fun writeFully(byteArray: ByteArray, offset: Int, limit: Int) { + writeChannel.writeByteArray(byteArray.copyOfRange(offset, offset + limit)) + writeChannel.flush() + } + override suspend fun readAvailable(buffer: ByteArray, offset: Int, limit: Int): Int { - if (!readChannel.isClosedForRead && readChannel.availableForRead == 0) return 0 - return readChannel.readAvailable(buffer, offset, limit) + if (readChannel.isClosedForRead && readChannel.availableForRead == 0) return -1 + val avail = readChannel.availableForRead + if (avail == 0) return 0 + val toRead = avail.coerceAtMost(limit) + val tmp = readChannel.readByteArray(toRead) + System.arraycopy(tmp, 0, buffer, offset, toRead) + return toRead + } + + override suspend fun readByte(): Byte = readChannel.ktorReadByte() + + override suspend fun readIntLittleEndian(): Int = Integer.reverseBytes(readChannel.readInt()) + + override suspend fun writeByte(value: Int) { + writeChannel.ktorWriteByte(value.toByte()) + writeChannel.flush() } - override suspend fun readByte(): Byte = readChannel.readByte() - override suspend fun readIntLittleEndian(): Int = readChannel.readIntLittleEndian() - override suspend fun writeByte(value: Int) = writeChannel.writeByte(value) - override suspend fun writeIntLittleEndian(value: Int) = writeChannel.writeIntLittleEndian(value) + override suspend fun writeIntLittleEndian(value: Int) { + writeChannel.writeInt(Integer.reverseBytes(value)) + writeChannel.flush() + } override suspend fun close() { try { - writeChannel.close() + writeChannel.flushAndClose() readChannel.cancel() ktorSocket.close() } catch (e: Exception) { diff --git a/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketFactory.kt b/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketFactory.kt index 8026060b5..a212f060b 100644 --- a/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketFactory.kt +++ b/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketFactory.kt @@ -18,7 +18,6 @@ package com.malinskiy.adam.transport.ktor import com.malinskiy.adam.transport.Socket import com.malinskiy.adam.transport.SocketFactory -import io.ktor.network.selector.ActorSelectorManager import io.ktor.network.selector.SelectorManager import io.ktor.network.sockets.aSocket import java.net.InetSocketAddress @@ -31,7 +30,7 @@ class KtorSocketFactory( private val connectTimeout: Long = 10_000, private val idleTimeout: Long = 30_000 ) : SocketFactory { - private val selectorManager: SelectorManager = ActorSelectorManager(coroutineContext) + private val selectorManager: SelectorManager = SelectorManager(coroutineContext) override suspend fun tcp(socketAddress: InetSocketAddress, connectTimeout: Long?, idleTimeout: Long?): Socket { val ktorSocketAddress = KtorSocketAddress(socketAddress.hostName, socketAddress.port) From 448e8ecd53e90046959962365e695dc2db36a259 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sat, 14 Feb 2026 15:27:43 +0000 Subject: [PATCH 03/50] feat: use square logcat --- adam/build.gradle.kts | 2 +- .../com/malinskiy/adam/log/AdamLogging.kt | 69 ++++++++++++++++++- gradle/libs.versions.toml | 4 +- transport-ktor/build.gradle.kts | 2 +- 4 files changed, 70 insertions(+), 7 deletions(-) diff --git a/adam/build.gradle.kts b/adam/build.gradle.kts index 0f26b4217..85b6d71ad 100644 --- a/adam/build.gradle.kts +++ b/adam/build.gradle.kts @@ -148,7 +148,7 @@ dependencies { implementation(libs.annotations) implementation(kotlin("stdlib-jdk8")) implementation(libs.coroutines.core) - implementation(libs.logging) + implementation(libs.logcat) api(libs.protobuf.lite) api(libs.grpc.protobuf.lite) api(libs.grpc.kotlin.stub) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/log/AdamLogging.kt b/adam/src/main/kotlin/com/malinskiy/adam/log/AdamLogging.kt index 36eb08fc2..5fcf58d76 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/log/AdamLogging.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/log/AdamLogging.kt @@ -16,9 +16,72 @@ package com.malinskiy.adam.log -import io.github.oshai.kotlinlogging.KLogger -import io.github.oshai.kotlinlogging.KotlinLogging +import logcat.LogPriority +import logcat.logcat +import logcat.asLog object AdamLogging { - fun logger(func: () -> Unit): KLogger = KotlinLogging.logger(func) + fun logger(func: () -> Unit): AdamLogger = AdamLogger() +} + +class AdamLogger { + inline fun debug(throwable: Throwable? = null, crossinline message: () -> String) { + logcat(LogPriority.DEBUG) { + buildString { + throwable?.let { + append(it.asLog()) + append("\n") + } + append(message()) + } + } + } + + inline fun info(throwable: Throwable? = null, crossinline message: () -> String) { + logcat(LogPriority.INFO) { + buildString { + throwable?.let { + append(it.asLog()) + append("\n") + } + append(message()) + } + } + } + + inline fun warn(throwable: Throwable? = null, crossinline message: () -> String) { + logcat(LogPriority.WARN) { + buildString { + throwable?.let { + append(it.asLog()) + append("\n") + } + append(message()) + } + } + } + + inline fun error(throwable: Throwable? = null, crossinline message: () -> String) { + logcat(LogPriority.ERROR) { + buildString { + throwable?.let { + append(it.asLog()) + append("\n") + } + append(message()) + } + } + } + + inline fun trace(throwable: Throwable? = null, crossinline message: () -> String) { + logcat(LogPriority.VERBOSE) { + buildString { + throwable?.let { + append(it.asLog()) + append("\n") + } + append(message()) + } + } + } } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b20d206bd..7b755dd16 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ kotlin = "2.3.10" coroutines = "1.10.2" annotations = "26.0.2" ktor = "3.4.0" -logging = "7.0.14" +logcat = "0.4" vertx = "5.0.7" apacheCommonsPool2 = "2.13.1" assertk = "0.28.1" @@ -36,7 +36,7 @@ apache-commons-pool2 = { module = "org.apache.commons:commons-pool2", version.re coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } coroutines-debug = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-debug", version.ref = "coroutines" } ktor-network = { module = "io.ktor:ktor-network-jvm", version.ref = "ktor" } -logging = { module = "io.github.oshai:kotlin-logging", version.ref = "logging" } +logcat = { module = "com.squareup.logcat:logcat", version.ref = "logcat" } vertx-core = { module = "io.vertx:vertx-core", version.ref = "vertx" } vertx-kotlin = { module = "io.vertx:vertx-lang-kotlin", version.ref = "vertx" } vertx-coroutines = { module = "io.vertx:vertx-lang-kotlin-coroutines", version.ref = "vertx" } diff --git a/transport-ktor/build.gradle.kts b/transport-ktor/build.gradle.kts index c8f70dce5..bea56bbf9 100644 --- a/transport-ktor/build.gradle.kts +++ b/transport-ktor/build.gradle.kts @@ -21,5 +21,5 @@ plugins { dependencies { implementation(project(":adam")) implementation(libs.ktor.network) - implementation(libs.logging) + implementation(libs.logcat) } From 8159c114781b9e36578ca8243885c74dbdbccc7e Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sat, 14 Feb 2026 15:37:04 +0000 Subject: [PATCH 04/50] chore(deps): remove org.jetbrains.dokka plugin from build files --- android-junit4-test-annotation-producer/build.gradle.kts | 1 - android-junit4/build.gradle.kts | 1 - androidx-screencapture/build.gradle.kts | 1 - 3 files changed, 3 deletions(-) diff --git a/android-junit4-test-annotation-producer/build.gradle.kts b/android-junit4-test-annotation-producer/build.gradle.kts index a7eb33718..a5936eaaa 100644 --- a/android-junit4-test-annotation-producer/build.gradle.kts +++ b/android-junit4-test-annotation-producer/build.gradle.kts @@ -17,7 +17,6 @@ plugins { id("adam.android.library") id("maven-publish") - id("org.jetbrains.dokka") } android { diff --git a/android-junit4/build.gradle.kts b/android-junit4/build.gradle.kts index 6cb52228b..ed1f50f81 100644 --- a/android-junit4/build.gradle.kts +++ b/android-junit4/build.gradle.kts @@ -17,7 +17,6 @@ plugins { id("adam.android.library") id("maven-publish") - id("org.jetbrains.dokka") } android { diff --git a/androidx-screencapture/build.gradle.kts b/androidx-screencapture/build.gradle.kts index 747a2f73e..d7a68372b 100644 --- a/androidx-screencapture/build.gradle.kts +++ b/androidx-screencapture/build.gradle.kts @@ -17,7 +17,6 @@ plugins { id("adam.android.library") id("maven-publish") - id("org.jetbrains.dokka") } android { From d7ea6fee4271e5b1e7b8a6d6101ca96cfe315433 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sat, 14 Feb 2026 15:39:41 +0000 Subject: [PATCH 05/50] docs: add AGENTS.md with build, test, and architecture details --- AGENTS.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..cc4dd4dbc --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,27 @@ +# AGENTS.md + +## Build & Test + +- Build: `./gradlew build` +- Lint: `./gradlew spotlessCheck` (fix: `./gradlew spotlessApply`) +- Run all tests: `./gradlew test` +- Run single test: `./gradlew :adam:test --tests "com.malinskiy.adam.ClassName.testMethod"` +- Integration tests: `./gradlew :adam:integrationTest` + +## Architecture + +Kotlin coroutine-based ADB (Android Debug Bridge) client library. Modules: + +- **adam** — Core ADB client (requests, transport, protobuf/gRPC). Main package: `com.malinskiy.adam` +- **transport-ktor** — Ktor-based transport implementation +- **android-junit4**, **android-testrunner-contract**, **androidx-screencapture** — Android test instrumentation helpers +- **server/** — Server stubs for testing (JUnit 4 & 5 variants) +- **buildSrc** — Convention plugins (`adam.jvm`, `adam.code.lint`, `adam.android.library`) + +## Code Style + +- Kotlin, JVM target 17. No star imports (star import threshold 999). Max line length 120. +- Formatting: ktlint (IntelliJ IDEA style) via Spotless. Trailing commas allowed. +- Tests use JUnit 4 + assertk + kotlinx.coroutines (`runBlocking`). Server stubs from `:server:server-stub-junit4`. +- Apache 2.0 license header required on all source files. +- 4-space indent, UTF-8, trailing whitespace trimmed, final newline required. From 33bf5c23e6edffd7f1d4ed2ca49548bf69d70aa5 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sat, 14 Feb 2026 15:57:30 +0000 Subject: [PATCH 06/50] ci: reduce CI due to approaching storage limits --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 3c401dcc9..f1e8cef71 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -70,7 +70,7 @@ jobs: strategy: fail-fast: false matrix: - api: [ 24, 25, 26, 28, 29, 30, 31, 33, 34, 35 ] + api: [ 24, 34, 35 ] steps: - uses: actions/checkout@v6 - name: Set up JDK 17 From 0137ad9e08cacf37df290cc01811bd6a72107dbb Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sat, 14 Feb 2026 16:40:21 +0000 Subject: [PATCH 07/50] chore: enable explicit api in adam module --- adam/build.gradle.kts | 4 +- .../adam/AndroidDebugBridgeClient.kt | 20 ++--- .../adam/AndroidDebugBridgeClientFactory.kt | 16 ++-- .../main/kotlin/com/malinskiy/adam/Const.kt | 80 +++++++++---------- .../com/malinskiy/adam/annotation/Features.kt | 2 +- .../adam/exception/PullFailedException.kt | 2 +- .../adam/exception/PushFailedException.kt | 2 +- .../exception/RequestRejectedException.kt | 2 +- .../exception/RequestValidationException.kt | 2 +- .../UnsupportedForwardingSpecException.kt | 2 +- .../UnsupportedImageProtocolException.kt | 2 +- .../UnsupportedSyncProtocolException.kt | 4 +- .../com/malinskiy/adam/extension/ByteArray.kt | 8 +- .../malinskiy/adam/extension/ByteBuffer.kt | 10 +-- .../com/malinskiy/adam/extension/Int.kt | 2 +- .../com/malinskiy/adam/extension/List.kt | 4 +- .../com/malinskiy/adam/extension/Socket.kt | 22 ++--- .../adam/interactor/AdbBinaryInteractor.kt | 4 +- .../interactor/DiscoverAdbSocketInteractor.kt | 6 +- .../adam/interactor/StartAdbInteractor.kt | 6 +- .../adam/interactor/StopAdbInteractor.kt | 6 +- .../com/malinskiy/adam/io/AsyncFileReader.kt | 10 +-- .../com/malinskiy/adam/io/AsyncFileWriter.kt | 6 +- .../com/malinskiy/adam/log/AdamLogging.kt | 16 ++-- .../adam/request/AccumulatingMultiRequest.kt | 2 +- .../adam/request/AsyncChannelRequest.kt | 10 +-- .../malinskiy/adam/request/ComplexRequest.kt | 6 +- .../com/malinskiy/adam/request/Feature.kt | 8 +- .../malinskiy/adam/request/MultiRequest.kt | 6 +- .../com/malinskiy/adam/request/Request.kt | 14 ++-- .../adam/request/SynchronousRequest.kt | 2 +- .../com/malinskiy/adam/request/Target.kt | 24 +++--- .../adam/request/ValidationResponse.kt | 24 +++--- .../adam/request/abb/AbbExecRequest.kt | 8 +- .../malinskiy/adam/request/abb/AbbRequest.kt | 6 +- .../malinskiy/adam/request/adbd/AdbdMode.kt | 10 +-- .../adam/request/adbd/RestartAdbdRequest.kt | 8 +- .../device/AsyncDeviceMonitorRequest.kt | 6 +- .../device/FetchDeviceFeaturesRequest.kt | 4 +- .../adam/request/device/ListDevicesRequest.kt | 12 +-- .../request/emu/EmulatorCommandRequest.kt | 12 +-- .../adam/request/file/ListFilesRequest.kt | 26 +++--- .../forwarding/ListPortForwardsRequest.kt | 4 +- .../adam/request/forwarding/LocalPortSpec.kt | 16 ++-- .../request/forwarding/PortForwardRequest.kt | 6 +- .../request/forwarding/PortForwardingRule.kt | 8 +- .../adam/request/forwarding/RemotePortSpec.kt | 32 ++++---- .../RemoveAllPortForwardsRequest.kt | 8 +- .../forwarding/RemovePortForwardRequest.kt | 8 +- .../BufferedImageScreenCaptureAdapter.kt | 2 +- .../adam/request/framebuffer/Color.kt | 12 +-- .../request/framebuffer/ColorModelFactory.kt | 4 +- .../adam/request/framebuffer/ColorSpace.kt | 8 +- .../adam/request/framebuffer/RawImage.kt | 36 ++++----- .../RawImageScreenCaptureAdapter.kt | 2 +- .../framebuffer/ScreenCaptureAdapter.kt | 6 +- .../framebuffer/ScreenCaptureRequest.kt | 4 +- .../request/logcat/ChanneledLogcatRequest.kt | 12 +-- .../adam/request/logcat/LogcatSinceFormat.kt | 8 +- .../adam/request/logcat/SyncLogcatRequest.kt | 4 +- .../request/mdns/ListMdnsServicesRequest.kt | 4 +- .../adam/request/mdns/MdnsCheckRequest.kt | 4 +- .../adam/request/mdns/MdnsService.kt | 8 +- .../malinskiy/adam/request/mdns/MdnsStatus.kt | 6 +- .../adam/request/misc/ConnectDeviceRequest.kt | 6 +- .../request/misc/DisconnectDeviceRequest.kt | 6 +- .../adam/request/misc/ExecInRequest.kt | 4 +- .../request/misc/FetchHostFeaturesRequest.kt | 4 +- .../misc/GetAdbServerVersionRequest.kt | 4 +- .../adam/request/misc/KillAdbRequest.kt | 8 +- .../adam/request/misc/PairDeviceRequest.kt | 6 +- .../adam/request/misc/RebootRequest.kt | 10 +-- .../adam/request/misc/ReconnectRequest.kt | 14 ++-- .../request/misc/RemountPartitionsRequest.kt | 8 +- .../adam/request/misc/SetDeviceRequest.kt | 4 +- .../pkg/AtomicInstallPackageRequest.kt | 6 +- .../pkg/InstallRemotePackageRequest.kt | 2 +- .../request/pkg/InstallSplitPackageRequest.kt | 10 +-- .../adam/request/pkg/LegacySideloadRequest.kt | 6 +- .../adam/request/pkg/PmListRequest.kt | 8 +- .../adam/request/pkg/SideloadRequest.kt | 6 +- .../pkg/StreamingPackageInstallRequest.kt | 10 +-- .../pkg/UninstallRemotePackageRequest.kt | 2 +- .../request/pkg/multi/AddSessionRequest.kt | 2 +- .../CreateIndividualPackageSessionRequest.kt | 2 +- .../multi/CreateMultiPackageSessionRequest.kt | 6 +- .../pkg/multi/CreateSessionResponse.kt | 2 +- .../request/pkg/multi/InstallCommitRequest.kt | 2 +- .../request/pkg/multi/InstallationPackage.kt | 8 +- .../multi/WriteIndividualPackageRequest.kt | 2 +- .../adam/request/prop/GetPropRequest.kt | 2 +- .../adam/request/prop/GetSinglePropRequest.kt | 4 +- .../reverse/ListReversePortForwardsRequest.kt | 4 +- .../RemoveAllReversePortForwardsRequest.kt | 8 +- .../RemoveReversePortForwardRequest.kt | 8 +- .../reverse/ReversePortForwardRequest.kt | 4 +- .../reverse/ReversePortForwardingRule.kt | 8 +- .../security/SetDmVerityCheckingRequest.kt | 8 +- .../shell/AsyncCompatShellCommandRequest.kt | 8 +- .../shell/v1/ChanneledShellCommandRequest.kt | 8 +- .../request/shell/v1/ShellCommandRequest.kt | 4 +- .../request/shell/v1/ShellCommandResult.kt | 8 +- .../v1/ShellResultResponseTransformer.kt | 2 +- .../shell/v1/SyncShellCommandRequest.kt | 14 ++-- .../shell/v2/ChanneledShellCommandRequest.kt | 18 ++--- .../adam/request/shell/v2/MessageType.kt | 8 +- .../request/shell/v2/ShellCommandRequest.kt | 4 +- .../request/shell/v2/ShellCommandResult.kt | 12 +-- .../shell/v2/SyncShellCommandRequest.kt | 6 +- .../adam/request/sync/PullRequest.kt | 2 +- .../adam/request/sync/PushRequest.kt | 2 +- .../request/sync/base/BasePullFileRequest.kt | 10 +-- .../request/sync/base/BasePushFileRequest.kt | 12 +-- .../sync/compat/CompatListFileRequest.kt | 2 +- .../sync/compat/CompatPullFileRequest.kt | 2 +- .../sync/compat/CompatPushFileRequest.kt | 2 +- .../sync/compat/CompatStatFileRequest.kt | 2 +- .../adam/request/sync/model/FileEntry.kt | 50 ++++++------ .../adam/request/sync/v1/ListFileRequest.kt | 4 +- .../adam/request/sync/v1/PullFileRequest.kt | 2 +- .../adam/request/sync/v1/PushFileRequest.kt | 2 +- .../adam/request/sync/v1/StatFileRequest.kt | 4 +- .../adam/request/sync/v2/CompressionType.kt | 4 +- .../adam/request/sync/v2/ListFileRequest.kt | 4 +- .../adam/request/sync/v2/PullFileRequest.kt | 2 +- .../adam/request/sync/v2/PushFileRequest.kt | 10 +-- .../adam/request/sync/v2/StatFileRequest.kt | 4 +- .../request/testrunner/InstrumentOptions.kt | 26 +++--- .../testrunner/InstrumentationSizeOption.kt | 2 +- .../adam/request/testrunner/TestEvent.kt | 24 +++--- .../adam/request/testrunner/TestIdentifier.kt | 6 +- .../request/testrunner/TestRunnerRequest.kt | 2 +- .../testrunner/model/SessionResultCode.kt | 2 +- .../adam/request/testrunner/model/State.kt | 10 +-- .../adam/request/testrunner/model/Status.kt | 8 +- .../request/testrunner/model/StatusKey.kt | 6 +- .../testrunner/model/TestStatusAggregator.kt | 8 +- .../request/testrunner/model/TokenType.kt | 2 +- .../InstrumentationResponseTransformer.kt | 8 +- ...ProtoInstrumentationResponseTransformer.kt | 2 +- .../transform/DumpResponseTransformer.kt | 2 +- .../ProgressiveResponseTransformer.kt | 6 +- .../request/transform/ResponseTransformer.kt | 6 +- .../transform/StringResponseTransformer.kt | 2 +- .../malinskiy/adam/transport/BufferFactory.kt | 20 ++--- .../com/malinskiy/adam/transport/Socket.kt | 26 +++--- .../malinskiy/adam/transport/SocketFactory.kt | 4 +- .../adam/transport/SuspendCloseable.kt | 6 +- .../adam/transport/TransportResponse.kt | 6 +- .../vertx/VariableSizeRecordParser.kt | 12 +-- .../adam/transport/vertx/VertxSocket.kt | 12 +-- .../transport/vertx/VertxSocketFactory.kt | 2 +- 152 files changed, 623 insertions(+), 621 deletions(-) diff --git a/adam/build.gradle.kts b/adam/build.gradle.kts index 85b6d71ad..6bfca34ba 100644 --- a/adam/build.gradle.kts +++ b/adam/build.gradle.kts @@ -25,7 +25,9 @@ plugins { id("idea") } - +kotlin { + explicitApi() +} protobuf { protoc { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/AndroidDebugBridgeClient.kt b/adam/src/main/kotlin/com/malinskiy/adam/AndroidDebugBridgeClient.kt index ce327b7ce..aa3629c30 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/AndroidDebugBridgeClient.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/AndroidDebugBridgeClient.kt @@ -36,14 +36,14 @@ import java.io.Closeable import java.net.InetAddress import java.net.InetSocketAddress -class AndroidDebugBridgeClient( - val port: Int, - val host: InetAddress, - val socketFactory: SocketFactory +public class AndroidDebugBridgeClient( + public val port: Int, + public val host: InetAddress, + public val socketFactory: SocketFactory ) : Closeable { private val socketAddress: InetSocketAddress = InetSocketAddress(host, port) - suspend fun execute(request: ComplexRequest, serial: String? = null): T { + public suspend fun execute(request: ComplexRequest, serial: String? = null): T { val validationResponse = request.validate() if (!validationResponse.success) { val requestSimpleClassName = request.javaClass.simpleName @@ -61,7 +61,7 @@ class AndroidDebugBridgeClient( } } - fun execute(request: AsyncChannelRequest, scope: CoroutineScope, serial: String? = null): ReceiveChannel { + public fun execute(request: AsyncChannelRequest, scope: CoroutineScope, serial: String? = null): ReceiveChannel { val validationResponse = request.validate() if (!validationResponse.success) { val requestSimpleClassName = request.javaClass.simpleName @@ -115,7 +115,7 @@ class AndroidDebugBridgeClient( } } - suspend fun execute(request: EmulatorCommandRequest): String { + public suspend fun execute(request: EmulatorCommandRequest): String { return socketFactory.tcp( socketAddress = request.address, idleTimeout = request.idleTimeoutOverride @@ -124,7 +124,7 @@ class AndroidDebugBridgeClient( } } - suspend fun execute(request: MultiRequest, serial: String? = null): T { + public suspend fun execute(request: MultiRequest, serial: String? = null): T { val validationResponse = request.validate() if (!validationResponse.success) { val requestSimpleClassName = request.javaClass.simpleName @@ -134,12 +134,12 @@ class AndroidDebugBridgeClient( return request.execute(this, serial) } - companion object { + public companion object { private val log = AdamLogging.logger {} } /** * If you're reusing the socket factory across multiple clients then this will affect another client */ - override fun close() = socketFactory.close() + override fun close(): Unit = socketFactory.close() } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/AndroidDebugBridgeClientFactory.kt b/adam/src/main/kotlin/com/malinskiy/adam/AndroidDebugBridgeClientFactory.kt index c70a2f29c..c3aca814e 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/AndroidDebugBridgeClientFactory.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/AndroidDebugBridgeClientFactory.kt @@ -23,15 +23,15 @@ import java.net.InetAddress import java.time.Duration import kotlin.coroutines.CoroutineContext -class AndroidDebugBridgeClientFactory { - var port: Int? = null - var host: InetAddress? = null - var coroutineContext: CoroutineContext? = null - var socketFactory: SocketFactory? = null - var idleTimeout: Duration? = null - var connectTimeout: Duration? = null +public class AndroidDebugBridgeClientFactory { + public var port: Int? = null + public var host: InetAddress? = null + public var coroutineContext: CoroutineContext? = null + public var socketFactory: SocketFactory? = null + public var idleTimeout: Duration? = null + public var connectTimeout: Duration? = null - fun build(): AndroidDebugBridgeClient { + public fun build(): AndroidDebugBridgeClient { return AndroidDebugBridgeClient( port = port ?: DiscoverAdbSocketInteractor().execute(), host = host ?: InetAddress.getByName(Const.DEFAULT_ADB_HOST), diff --git a/adam/src/main/kotlin/com/malinskiy/adam/Const.kt b/adam/src/main/kotlin/com/malinskiy/adam/Const.kt index 00bd149d9..31411b4d8 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/Const.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/Const.kt @@ -16,44 +16,44 @@ package com.malinskiy.adam -object Const { - const val MAX_REMOTE_PATH_LENGTH = 1024 - const val DEFAULT_BUFFER_SIZE = 1024 - val DEFAULT_TRANSPORT_ENCODING = Charsets.UTF_8 - const val DEFAULT_ADB_HOST = "127.0.0.1" - const val DEFAULT_ADB_PORT = 5037 +public object Const { + public const val MAX_REMOTE_PATH_LENGTH: Int = 1024 + public const val DEFAULT_BUFFER_SIZE: Int = 1024 + public val DEFAULT_TRANSPORT_ENCODING: java.nio.charset.Charset = Charsets.UTF_8 + public const val DEFAULT_ADB_HOST: String = "127.0.0.1" + public const val DEFAULT_ADB_PORT: Int = 5037 - const val SERVER_PORT_ENV_VAR = "ANDROID_ADB_SERVER_PORT" - const val MAX_PACKET_LENGTH = 16384 - const val MAX_FILE_PACKET_LENGTH = 64 * 1024 + public const val SERVER_PORT_ENV_VAR: String = "ANDROID_ADB_SERVER_PORT" + public const val MAX_PACKET_LENGTH: Int = 16384 + public const val MAX_FILE_PACKET_LENGTH: Int = 64 * 1024 - const val MAX_PROTOBUF_LOGCAT_LENGTH = 10_000 - const val MAX_PROTOBUF_PACKET_LENGTH = 10 * 1024 * 1024L //10Mb - const val TEST_LOGCAT_METRIC = "com.malinskiy.adam.logcat" + public const val MAX_PROTOBUF_LOGCAT_LENGTH: Int = 10_000 + public const val MAX_PROTOBUF_PACKET_LENGTH: Long = 10 * 1024 * 1024L //10Mb + public const val TEST_LOGCAT_METRIC: String = "com.malinskiy.adam.logcat" - const val ANDROID_FILE_SEPARATOR = "/" - val SYNC_IGNORED_FILES = setOf(".", "..") + public const val ANDROID_FILE_SEPARATOR: String = "/" + public val SYNC_IGNORED_FILES: Set = setOf(".", "..") - object Message { - val OKAY = byteArrayOf('O'.code.toByte(), 'K'.code.toByte(), 'A'.code.toByte(), 'Y'.code.toByte()) - val FAIL = byteArrayOf('F'.code.toByte(), 'A'.code.toByte(), 'I'.code.toByte(), 'L'.code.toByte()) + public object Message { + public val OKAY: ByteArray = byteArrayOf('O'.code.toByte(), 'K'.code.toByte(), 'A'.code.toByte(), 'Y'.code.toByte()) + public val FAIL: ByteArray = byteArrayOf('F'.code.toByte(), 'A'.code.toByte(), 'I'.code.toByte(), 'L'.code.toByte()) - val DATA = byteArrayOf('D'.code.toByte(), 'A'.code.toByte(), 'T'.code.toByte(), 'A'.code.toByte()) - val DONE = byteArrayOf('D'.code.toByte(), 'O'.code.toByte(), 'N'.code.toByte(), 'E'.code.toByte()) + public val DATA: ByteArray = byteArrayOf('D'.code.toByte(), 'A'.code.toByte(), 'T'.code.toByte(), 'A'.code.toByte()) + public val DONE: ByteArray = byteArrayOf('D'.code.toByte(), 'O'.code.toByte(), 'N'.code.toByte(), 'E'.code.toByte()) - val LSTAT_V1 = byteArrayOf('S'.code.toByte(), 'T'.code.toByte(), 'A'.code.toByte(), 'T'.code.toByte()) - val LIST_V1 = byteArrayOf('L'.code.toByte(), 'I'.code.toByte(), 'S'.code.toByte(), 'T'.code.toByte()) - val DENT_V1 = byteArrayOf('D'.code.toByte(), 'E'.code.toByte(), 'N'.code.toByte(), 'T'.code.toByte()) - val SEND_V1 = byteArrayOf('S'.code.toByte(), 'E'.code.toByte(), 'N'.code.toByte(), 'D'.code.toByte()) - val RECV_V1 = byteArrayOf('R'.code.toByte(), 'E'.code.toByte(), 'C'.code.toByte(), 'V'.code.toByte()) + public val LSTAT_V1: ByteArray = byteArrayOf('S'.code.toByte(), 'T'.code.toByte(), 'A'.code.toByte(), 'T'.code.toByte()) + public val LIST_V1: ByteArray = byteArrayOf('L'.code.toByte(), 'I'.code.toByte(), 'S'.code.toByte(), 'T'.code.toByte()) + public val DENT_V1: ByteArray = byteArrayOf('D'.code.toByte(), 'E'.code.toByte(), 'N'.code.toByte(), 'T'.code.toByte()) + public val SEND_V1: ByteArray = byteArrayOf('S'.code.toByte(), 'E'.code.toByte(), 'N'.code.toByte(), 'D'.code.toByte()) + public val RECV_V1: ByteArray = byteArrayOf('R'.code.toByte(), 'E'.code.toByte(), 'C'.code.toByte(), 'V'.code.toByte()) - val LIST_V2 = byteArrayOf('L'.code.toByte(), 'I'.code.toByte(), 'S'.code.toByte(), '2'.code.toByte()) - val DENT_V2 = byteArrayOf('D'.code.toByte(), 'N'.code.toByte(), 'T'.code.toByte(), '2'.code.toByte()) - val LSTAT_V2 = byteArrayOf('L'.code.toByte(), 'S'.code.toByte(), 'T'.code.toByte(), '2'.code.toByte()) - val RECV_V2 = byteArrayOf('R'.code.toByte(), 'C'.code.toByte(), 'V'.code.toByte(), '2'.code.toByte()) - val SEND_V2 = byteArrayOf('S'.code.toByte(), 'N'.code.toByte(), 'D'.code.toByte(), '2'.code.toByte()) + public val LIST_V2: ByteArray = byteArrayOf('L'.code.toByte(), 'I'.code.toByte(), 'S'.code.toByte(), '2'.code.toByte()) + public val DENT_V2: ByteArray = byteArrayOf('D'.code.toByte(), 'N'.code.toByte(), 'T'.code.toByte(), '2'.code.toByte()) + public val LSTAT_V2: ByteArray = byteArrayOf('L'.code.toByte(), 'S'.code.toByte(), 'T'.code.toByte(), '2'.code.toByte()) + public val RECV_V2: ByteArray = byteArrayOf('R'.code.toByte(), 'C'.code.toByte(), 'V'.code.toByte(), '2'.code.toByte()) + public val SEND_V2: ByteArray = byteArrayOf('S'.code.toByte(), 'N'.code.toByte(), 'D'.code.toByte(), '2'.code.toByte()) - val DONEDONE = + public val DONEDONE: ByteArray = byteArrayOf( 'D'.code.toByte(), 'O'.code.toByte(), @@ -64,7 +64,7 @@ object Const { 'N'.code.toByte(), 'E'.code.toByte() ) - val FAILFAIL = + public val FAILFAIL: ByteArray = byteArrayOf( 'F'.code.toByte(), 'A'.code.toByte(), @@ -77,14 +77,14 @@ object Const { ) } - object FileType { - val S_IFMT = "170000".toUInt(8) - val S_IFIFO = "10000".toUInt(8) - val S_IFCHR = "20000".toUInt(8) - val S_IFDIR = "40000".toUInt(8) - val S_IFBLK = "60000".toUInt(8) - val S_IFREG = "100000".toUInt(8) - val S_IFLNK = "120000".toUInt(8) - val S_IFSOCK = "140000".toUInt(8) + public object FileType { + public val S_IFMT: UInt = "170000".toUInt(8) + public val S_IFIFO: UInt = "10000".toUInt(8) + public val S_IFCHR: UInt = "20000".toUInt(8) + public val S_IFDIR: UInt = "40000".toUInt(8) + public val S_IFBLK: UInt = "60000".toUInt(8) + public val S_IFREG: UInt = "100000".toUInt(8) + public val S_IFLNK: UInt = "120000".toUInt(8) + public val S_IFSOCK: UInt = "140000".toUInt(8) } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/annotation/Features.kt b/adam/src/main/kotlin/com/malinskiy/adam/annotation/Features.kt index 03d423970..2263c9b3a 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/annotation/Features.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/annotation/Features.kt @@ -25,4 +25,4 @@ import com.malinskiy.adam.request.Feature @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.RUNTIME) @MustBeDocumented -annotation class Features(vararg val features: Feature) +public annotation class Features(vararg val features: Feature) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/exception/PullFailedException.kt b/adam/src/main/kotlin/com/malinskiy/adam/exception/PullFailedException.kt index 9c0ec73d8..898eb5a75 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/exception/PullFailedException.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/exception/PullFailedException.kt @@ -16,4 +16,4 @@ package com.malinskiy.adam.exception -class PullFailedException(message: String) : RuntimeException(message) \ No newline at end of file +public class PullFailedException(message: String) : RuntimeException(message) \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/exception/PushFailedException.kt b/adam/src/main/kotlin/com/malinskiy/adam/exception/PushFailedException.kt index c6c920280..014864d48 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/exception/PushFailedException.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/exception/PushFailedException.kt @@ -16,4 +16,4 @@ package com.malinskiy.adam.exception -class PushFailedException(message: String) : RuntimeException(message) \ No newline at end of file +public class PushFailedException(message: String) : RuntimeException(message) \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/exception/RequestRejectedException.kt b/adam/src/main/kotlin/com/malinskiy/adam/exception/RequestRejectedException.kt index 2b4921c63..1b9957b07 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/exception/RequestRejectedException.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/exception/RequestRejectedException.kt @@ -16,4 +16,4 @@ package com.malinskiy.adam.exception -class RequestRejectedException(message: String) : RuntimeException(message) +public class RequestRejectedException(message: String) : RuntimeException(message) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/exception/RequestValidationException.kt b/adam/src/main/kotlin/com/malinskiy/adam/exception/RequestValidationException.kt index 31adb3e0b..04f7d2ace 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/exception/RequestValidationException.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/exception/RequestValidationException.kt @@ -16,4 +16,4 @@ package com.malinskiy.adam.exception -class RequestValidationException(message: String) : RuntimeException(message) \ No newline at end of file +public class RequestValidationException(message: String) : RuntimeException(message) \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedForwardingSpecException.kt b/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedForwardingSpecException.kt index 2374fe7d2..e759a0f65 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedForwardingSpecException.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedForwardingSpecException.kt @@ -16,4 +16,4 @@ package com.malinskiy.adam.exception -class UnsupportedForwardingSpecException(type: String) : RuntimeException("Unknown type $type for forwarding spec") \ No newline at end of file +public class UnsupportedForwardingSpecException(type: String) : RuntimeException("Unknown type $type for forwarding spec") \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedImageProtocolException.kt b/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedImageProtocolException.kt index 0b58245ce..2f4da3a16 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedImageProtocolException.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedImageProtocolException.kt @@ -16,4 +16,4 @@ package com.malinskiy.adam.exception -class UnsupportedImageProtocolException(version: Int?) : RuntimeException("Unsupported version $version") \ No newline at end of file +public class UnsupportedImageProtocolException(version: Int?) : RuntimeException("Unsupported version $version") \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedSyncProtocolException.kt b/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedSyncProtocolException.kt index 32c2cfbbb..3b83639af 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedSyncProtocolException.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedSyncProtocolException.kt @@ -16,6 +16,6 @@ package com.malinskiy.adam.exception -class UnsupportedSyncProtocolException(message: String) : RuntimeException(message) { - constructor() : this("Unsupported sync: protocol response") +public class UnsupportedSyncProtocolException(message: String) : RuntimeException(message) { + public constructor() : this("Unsupported sync: protocol response") } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/extension/ByteArray.kt b/adam/src/main/kotlin/com/malinskiy/adam/extension/ByteArray.kt index fce6f26fa..640f97dd5 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/extension/ByteArray.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/extension/ByteArray.kt @@ -16,18 +16,18 @@ package com.malinskiy.adam.extension -fun ByteArray.toInt(): Int { +public fun ByteArray.toInt(): Int { return (this[0].toInt() and 0x000000FF) or (this[1].toInt() and 0x000000FF shl 8) or (this[2].toInt() and 0x000000FF shl 16) or (this[3].toInt() and 0x000000FF shl 24) } -fun ByteArray.toUInt(): UInt { +public fun ByteArray.toUInt(): UInt { return toInt().toUInt() } -fun ByteArray.toLong(): Long { +public fun ByteArray.toLong(): Long { return (this[0].toInt() and 0x000000FF).toLong() or (this[1].toInt() and 0x000000FF shl 8).toLong() or (this[2].toInt() and 0x000000FF shl 16).toLong() or @@ -38,6 +38,6 @@ fun ByteArray.toLong(): Long { (this[7].toInt() and 0x000000FF shl 56).toLong() } -fun ByteArray.toULong(): ULong { +public fun ByteArray.toULong(): ULong { return toLong().toULong() } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/extension/ByteBuffer.kt b/adam/src/main/kotlin/com/malinskiy/adam/extension/ByteBuffer.kt index 6ca8a8d48..5f89f3dbd 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/extension/ByteBuffer.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/extension/ByteBuffer.kt @@ -24,8 +24,8 @@ import java.nio.ByteBuffer * * java.lang.NoSuchMethodError: java.nio.ByteBuffer.xxx()Ljava/nio/ByteBuffer; */ -fun ByteBuffer.compatRewind() = ((this as Buffer).rewind() as ByteBuffer) -fun ByteBuffer.compatLimit(newLimit: Int) = ((this as Buffer).limit(newLimit) as ByteBuffer) -fun ByteBuffer.compatPosition(newLimit: Int) = ((this as Buffer).position(newLimit) as ByteBuffer) -fun ByteBuffer.compatFlip() = ((this as Buffer).flip() as ByteBuffer) -fun ByteBuffer.compatClear() = ((this as Buffer).clear() as ByteBuffer) +public fun ByteBuffer.compatRewind(): ByteBuffer = ((this as Buffer).rewind() as ByteBuffer) +public fun ByteBuffer.compatLimit(newLimit: Int): ByteBuffer = ((this as Buffer).limit(newLimit) as ByteBuffer) +public fun ByteBuffer.compatPosition(newLimit: Int): ByteBuffer = ((this as Buffer).position(newLimit) as ByteBuffer) +public fun ByteBuffer.compatFlip(): ByteBuffer = ((this as Buffer).flip() as ByteBuffer) +public fun ByteBuffer.compatClear(): ByteBuffer = ((this as Buffer).clear() as ByteBuffer) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/extension/Int.kt b/adam/src/main/kotlin/com/malinskiy/adam/extension/Int.kt index 9b69867ff..c5cbabb25 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/extension/Int.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/extension/Int.kt @@ -16,7 +16,7 @@ package com.malinskiy.adam.extension -fun Int.toByteArray(): ByteArray { +public fun Int.toByteArray(): ByteArray { return byteArrayOf( this.ushr(24).toByte(), ((this and 0xFF0000) shr 16).toByte(), diff --git a/adam/src/main/kotlin/com/malinskiy/adam/extension/List.kt b/adam/src/main/kotlin/com/malinskiy/adam/extension/List.kt index 1aa470f6c..ad3f59467 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/extension/List.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/extension/List.kt @@ -16,6 +16,6 @@ package com.malinskiy.adam.extension -fun List.bashEscape() = "'" + joinToString(" ") { it.replace("'", "'\\''") } + "'" +public fun List.bashEscape(): String = "'" + joinToString(" ") { it.replace("'", "'\\''") } + "'" -fun String.bashEscape() = "'" + replace("'", "'\\''") + "'" +public fun String.bashEscape(): String = "'" + replace("'", "'\\''") + "'" diff --git a/adam/src/main/kotlin/com/malinskiy/adam/extension/Socket.kt b/adam/src/main/kotlin/com/malinskiy/adam/extension/Socket.kt index 770d4d026..30d59e82d 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/extension/Socket.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/extension/Socket.kt @@ -35,7 +35,7 @@ import kotlin.coroutines.CoroutineContext /** * Copies up to limit bytes into transformer using buffer. If limit is null - copy until EOF */ -suspend fun Socket.copyTo(transformer: ResponseTransformer, buffer: ByteArray, limit: Long? = null): Long { +public suspend fun Socket.copyTo(transformer: ResponseTransformer, buffer: ByteArray, limit: Long? = null): Long { var processed = 0L loop@ while (true) { val toRead = when { @@ -76,11 +76,11 @@ suspend fun Socket.copyTo(transformer: ResponseTransformer, buffer: ByteA * TODO: rewrite * Assumes buffer hasArray == true */ -suspend fun Socket.copyTo(transformer: ResponseTransformer, buffer: ByteBuffer) = copyTo(transformer, buffer.array()) -suspend fun Socket.copyTo(transformer: ResponseTransformer, buffer: ByteBuffer, limit: Long? = null) = +public suspend fun Socket.copyTo(transformer: ResponseTransformer, buffer: ByteBuffer): Long = copyTo(transformer, buffer.array()) +public suspend fun Socket.copyTo(transformer: ResponseTransformer, buffer: ByteBuffer, limit: Long? = null): Long = copyTo(transformer, buffer.array(), limit) -suspend fun Socket.readOptionalProtocolString(): String? { +public suspend fun Socket.readOptionalProtocolString(): String? { val responseLength = withDefaultBuffer { val transformer = StringResponseTransformer() copyTo(transformer, this, limit = 4L) @@ -101,7 +101,7 @@ suspend fun Socket.readOptionalProtocolString(): String? { /** * @throws RequestRejectedException */ -suspend fun Socket.readProtocolString(): String { +public suspend fun Socket.readProtocolString(): String { withMaxPacketBuffer { val transformer = StringResponseTransformer() val copied = copyTo(transformer, this, limit = 4L) @@ -127,7 +127,7 @@ private fun ByteBuffer.isOkay(): Boolean { return true } -suspend fun Socket.readStatus(): String { +public suspend fun Socket.readStatus(): String { withDefaultBuffer { val transformer = StringResponseTransformer() copyTo(transformer, this) @@ -135,11 +135,11 @@ suspend fun Socket.readStatus(): String { } } -suspend fun Socket.write(request: ByteArray, length: Int? = null) { +public suspend fun Socket.write(request: ByteArray, length: Int? = null) { writeFully(request, 0, length ?: request.size) } -suspend fun Socket.writeFile(file: File, coroutineContext: CoroutineContext) { +public suspend fun Socket.writeFile(file: File, coroutineContext: CoroutineContext) { AsyncFileReader(file, coroutineContext = coroutineContext).use { reader -> reader.start() while (true) { @@ -159,7 +159,7 @@ suspend fun Socket.writeFile(file: File, coroutineContext: CoroutineContext) { } } -suspend fun Socket.writeSyncRequest(type: ByteArray, remotePath: String) { +public suspend fun Socket.writeSyncRequest(type: ByteArray, remotePath: String) { val path = remotePath.toByteArray(Const.DEFAULT_TRANSPORT_ENCODING) val size = path.size.toByteArray().reversedArray() @@ -172,7 +172,7 @@ suspend fun Socket.writeSyncRequest(type: ByteArray, remotePath: String) { } } -suspend fun Socket.writeSyncV2Request(type: ByteArray, remotePath: String, flags: Int, mode: Int? = null) { +public suspend fun Socket.writeSyncV2Request(type: ByteArray, remotePath: String, flags: Int, mode: Int? = null) { val path = remotePath.toByteArray(Const.DEFAULT_TRANSPORT_ENCODING) withDefaultBuffer { @@ -194,7 +194,7 @@ suspend fun Socket.writeSyncV2Request(type: ByteArray, remotePath: String, flags } } -suspend fun Socket.readTransportResponse(): TransportResponse { +public suspend fun Socket.readTransportResponse(): TransportResponse { val ok = withDefaultBuffer { compatLimit(4) readFully(this) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/interactor/AdbBinaryInteractor.kt b/adam/src/main/kotlin/com/malinskiy/adam/interactor/AdbBinaryInteractor.kt index b764e4c17..3878f78f0 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/interactor/AdbBinaryInteractor.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/interactor/AdbBinaryInteractor.kt @@ -22,8 +22,8 @@ import java.lang.ProcessBuilder.Redirect import java.util.* @Suppress("NewApi") -open class AdbBinaryInteractor { - suspend fun execute( +public open class AdbBinaryInteractor { + public suspend fun execute( adbBinary: File?, androidHome: File?, vararg cmd: String diff --git a/adam/src/main/kotlin/com/malinskiy/adam/interactor/DiscoverAdbSocketInteractor.kt b/adam/src/main/kotlin/com/malinskiy/adam/interactor/DiscoverAdbSocketInteractor.kt index 73179b7af..28ed3a366 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/interactor/DiscoverAdbSocketInteractor.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/interactor/DiscoverAdbSocketInteractor.kt @@ -19,8 +19,8 @@ package com.malinskiy.adam.interactor import com.malinskiy.adam.Const import com.malinskiy.adam.log.AdamLogging -class DiscoverAdbSocketInteractor { - fun execute() = discover("system property") { System.getProperty(Const.SERVER_PORT_ENV_VAR) } +public class DiscoverAdbSocketInteractor { + public fun execute(): Int = discover("system property") { System.getProperty(Const.SERVER_PORT_ENV_VAR) } ?: discover("env var") { System.getenv(Const.SERVER_PORT_ENV_VAR) } ?: Const.DEFAULT_ADB_PORT @@ -49,7 +49,7 @@ class DiscoverAdbSocketInteractor { else -> true } - companion object { + public companion object { private val log = AdamLogging.logger {} } } \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/interactor/StartAdbInteractor.kt b/adam/src/main/kotlin/com/malinskiy/adam/interactor/StartAdbInteractor.kt index fc7304a6d..dc78d778d 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/interactor/StartAdbInteractor.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/interactor/StartAdbInteractor.kt @@ -19,10 +19,10 @@ package com.malinskiy.adam.interactor import com.malinskiy.adam.Const import java.io.File -class StartAdbInteractor : AdbBinaryInteractor() { - suspend fun execute( +public class StartAdbInteractor : AdbBinaryInteractor() { + public suspend fun execute( adbBinary: File? = null, androidHome: File? = null, serverPort: Int = Const.DEFAULT_ADB_PORT - ) = execute(adbBinary, androidHome, "-P", serverPort.toString(), "start-server") + ): Boolean = execute(adbBinary, androidHome, "-P", serverPort.toString(), "start-server") } \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/interactor/StopAdbInteractor.kt b/adam/src/main/kotlin/com/malinskiy/adam/interactor/StopAdbInteractor.kt index 6c6ccd94c..53c3a08d2 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/interactor/StopAdbInteractor.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/interactor/StopAdbInteractor.kt @@ -19,10 +19,10 @@ package com.malinskiy.adam.interactor import com.malinskiy.adam.Const import java.io.File -class StopAdbInteractor : AdbBinaryInteractor() { - suspend fun execute( +public class StopAdbInteractor : AdbBinaryInteractor() { + public suspend fun execute( adbBinary: File? = null, androidHome: File? = null, serverPort: Int = Const.DEFAULT_ADB_PORT - ) = execute(adbBinary, androidHome, "-P", serverPort.toString(), "kill-server") + ): Boolean = execute(adbBinary, androidHome, "-P", serverPort.toString(), "kill-server") } \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/io/AsyncFileReader.kt b/adam/src/main/kotlin/com/malinskiy/adam/io/AsyncFileReader.kt index cb89931f4..9626985ce 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/io/AsyncFileReader.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/io/AsyncFileReader.kt @@ -35,7 +35,7 @@ import kotlin.coroutines.CoroutineContext /** * Reads file using passed coroutineContext and pushes updates of predefined structure using channel */ -class AsyncFileReader( +public class AsyncFileReader( file: File, private val start: Long = 0, private val offset: Int = 0, @@ -47,7 +47,7 @@ class AsyncFileReader( private var job: Job? = null @Suppress("BlockingMethodInNonBlockingContext") - fun start() { + public fun start() { job = launch { fileChannel.use { readChannel -> readChannel.skip(start) @@ -70,7 +70,7 @@ class AsyncFileReader( } } - suspend fun read(block: suspend (ByteBuffer?) -> T): T { + public suspend fun read(block: suspend (ByteBuffer?) -> T): T { return block(bufferChannel.receiveCatching().getOrNull()) } @@ -80,7 +80,7 @@ class AsyncFileReader( } } -suspend fun AsyncFileReader.copyTo(socket: Socket) { +public suspend fun AsyncFileReader.copyTo(socket: Socket) { while (true) { val closed = read { try { @@ -95,7 +95,7 @@ suspend fun AsyncFileReader.copyTo(socket: Socket) { } } -suspend fun AsyncFileReader.copyTo(transformer: ResponseTransformer) { +public suspend fun AsyncFileReader.copyTo(transformer: ResponseTransformer) { while (true) { val closed = read { try { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/io/AsyncFileWriter.kt b/adam/src/main/kotlin/com/malinskiy/adam/io/AsyncFileWriter.kt index b690566e5..149a489f4 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/io/AsyncFileWriter.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/io/AsyncFileWriter.kt @@ -28,7 +28,7 @@ import java.io.File import java.nio.ByteBuffer import kotlin.coroutines.CoroutineContext -class AsyncFileWriter( +public class AsyncFileWriter( file: File, override val coroutineContext: CoroutineContext = Dispatchers.IO ) : CoroutineScope, SuspendCloseable { @@ -45,7 +45,7 @@ class AsyncFileWriter( private var job: Job? = null @Suppress("BlockingMethodInNonBlockingContext") - fun start() { + public fun start() { job = launch { for (buffer in bufferChannel) { fileChannel.write(buffer.array(), buffer.position(), buffer.limit()) @@ -54,7 +54,7 @@ class AsyncFileWriter( } } - suspend fun write(byteBuffer: ByteBuffer) { + public suspend fun write(byteBuffer: ByteBuffer) { bufferChannel.send(byteBuffer) } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/log/AdamLogging.kt b/adam/src/main/kotlin/com/malinskiy/adam/log/AdamLogging.kt index 5fcf58d76..43ae14c3b 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/log/AdamLogging.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/log/AdamLogging.kt @@ -20,12 +20,12 @@ import logcat.LogPriority import logcat.logcat import logcat.asLog -object AdamLogging { - fun logger(func: () -> Unit): AdamLogger = AdamLogger() +public object AdamLogging { + public fun logger(func: () -> Unit): AdamLogger = AdamLogger() } -class AdamLogger { - inline fun debug(throwable: Throwable? = null, crossinline message: () -> String) { +public class AdamLogger { + public inline fun debug(throwable: Throwable? = null, crossinline message: () -> String) { logcat(LogPriority.DEBUG) { buildString { throwable?.let { @@ -37,7 +37,7 @@ class AdamLogger { } } - inline fun info(throwable: Throwable? = null, crossinline message: () -> String) { + public inline fun info(throwable: Throwable? = null, crossinline message: () -> String) { logcat(LogPriority.INFO) { buildString { throwable?.let { @@ -49,7 +49,7 @@ class AdamLogger { } } - inline fun warn(throwable: Throwable? = null, crossinline message: () -> String) { + public inline fun warn(throwable: Throwable? = null, crossinline message: () -> String) { logcat(LogPriority.WARN) { buildString { throwable?.let { @@ -61,7 +61,7 @@ class AdamLogger { } } - inline fun error(throwable: Throwable? = null, crossinline message: () -> String) { + public inline fun error(throwable: Throwable? = null, crossinline message: () -> String) { logcat(LogPriority.ERROR) { buildString { throwable?.let { @@ -73,7 +73,7 @@ class AdamLogger { } } - inline fun trace(throwable: Throwable? = null, crossinline message: () -> String) { + public inline fun trace(throwable: Throwable? = null, crossinline message: () -> String) { logcat(LogPriority.VERBOSE) { buildString { throwable?.let { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/AccumulatingMultiRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/AccumulatingMultiRequest.kt index 0650090aa..f1c9821c1 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/AccumulatingMultiRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/AccumulatingMultiRequest.kt @@ -19,7 +19,7 @@ package com.malinskiy.adam.request /** * MultiRequest that accumulates char sequence responses */ -abstract class AccumulatingMultiRequest : MultiRequest() { +public abstract class AccumulatingMultiRequest : MultiRequest() { private val responseBuffer by lazy { StringBuilder() } protected val accumulatedResponse: String get() = responseBuffer.toString() diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/AsyncChannelRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/AsyncChannelRequest.kt index 68b1fedbe..43d0accb8 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/AsyncChannelRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/AsyncChannelRequest.kt @@ -24,8 +24,8 @@ import kotlinx.coroutines.channels.SendChannel * Read and write are called in sequence, hence you have to give the control flow back if you want * cooperative multitasking to happen */ -abstract class AsyncChannelRequest( - val channel: ReceiveChannel? = null, +public abstract class AsyncChannelRequest( + public val channel: ReceiveChannel? = null, target: Target = NonSpecifiedTarget, socketIdleTimeout: Long? = null ) : Request(target, socketIdleTimeout) { @@ -33,16 +33,16 @@ abstract class AsyncChannelRequest( /** * Called after the initial OKAY confirmation */ - abstract suspend fun readElement(socket: Socket, sendChannel: SendChannel): Boolean + public abstract suspend fun readElement(socket: Socket, sendChannel: SendChannel): Boolean /** * Called after each readElement */ - abstract suspend fun writeElement(element: I, socket: Socket) + public abstract suspend fun writeElement(element: I, socket: Socket) /** * Optionally send a message * The transport connection is not available at this point */ - open suspend fun close(channel: SendChannel) = Unit + public open suspend fun close(channel: SendChannel): Unit = Unit } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/ComplexRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/ComplexRequest.kt index 961d5f573..ce6fa81e1 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/ComplexRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/ComplexRequest.kt @@ -22,16 +22,16 @@ import com.malinskiy.adam.transport.Socket * This type of request starts with single serialized request * and then proceed to do several reads and writes that have dynamic size */ -abstract class ComplexRequest(target: Target = NonSpecifiedTarget, socketIdleTimeout: Long? = null) : +public abstract class ComplexRequest(target: Target = NonSpecifiedTarget, socketIdleTimeout: Long? = null) : Request(target, socketIdleTimeout) { /** * Some requests ignore the initial OKAY/FAIL response and instead stream the actual response * To implement these we allow overriding this method */ - open suspend fun process(socket: Socket): T { + public open suspend fun process(socket: Socket): T { handshake(socket) return readElement(socket) } - abstract suspend fun readElement(socket: Socket): T + public abstract suspend fun readElement(socket: Socket): T } \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/Feature.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/Feature.kt index 4a07a21d4..10f3b7c9e 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/Feature.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/Feature.kt @@ -21,7 +21,7 @@ import java.util.* /** * Each entry represents a service that is supported by the adbd on the device */ -enum class Feature { +public enum class Feature { SHELL_V2, /** @@ -101,13 +101,13 @@ enum class Feature { */ SENDRECV_V2_DRY_RUN_SEND; - fun value() = name.lowercase(Locale.ENGLISH) + public fun value(): String = name.lowercase(Locale.ENGLISH) - companion object { + public companion object { /** * see adb/transport.cpp for up-to-date list */ - fun of(value: String) = when (value) { + public fun of(value: String): Feature? = when (value) { "shell_v2" -> SHELL_V2 "cmd" -> CMD "stat_v2" -> STAT_V2 diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/MultiRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/MultiRequest.kt index 1d049bd9a..1fd1075b6 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/MultiRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/MultiRequest.kt @@ -21,7 +21,7 @@ import com.malinskiy.adam.AndroidDebugBridgeClient /** * This type of request is a wrapper of a sequence of requests */ -abstract class MultiRequest { - abstract suspend fun execute(androidDebugBridgeClient: AndroidDebugBridgeClient, serial: String?): T - open fun validate(): ValidationResponse = ValidationResponse.Success +public abstract class MultiRequest { + public abstract suspend fun execute(androidDebugBridgeClient: AndroidDebugBridgeClient, serial: String?): T + public open fun validate(): ValidationResponse = ValidationResponse.Success } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/Request.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/Request.kt index 05a478dc7..668c64f42 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/Request.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/Request.kt @@ -30,18 +30,18 @@ import java.io.UnsupportedEncodingException * * @param socketIdleTimeout override for socket idle timeout */ -abstract class Request( - val target: Target = HostTarget, - val socketIdleTimeout: Long? = null +public abstract class Request( + public val target: Target = HostTarget, + public val socketIdleTimeout: Long? = null ) { /** * Some requests require a device serial to be passed to the request itself by means of * @see https://android.googlesource.com/platform/system/core/+/refs/heads/master/adb/SERVICES.TXT */ - abstract fun serialize(): ByteArray + public abstract fun serialize(): ByteArray - open suspend fun handshake(socket: Socket) { + public open suspend fun handshake(socket: Socket) { val request = serialize() socket.write(request) val response = socket.readTransportResponse() @@ -68,9 +68,9 @@ abstract class Request( return result } - open fun validate(): ValidationResponse = ValidationResponse.Success + public open fun validate(): ValidationResponse = ValidationResponse.Success - companion object { + public companion object { private val log = AdamLogging.logger {} } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/SynchronousRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/SynchronousRequest.kt index 146e23843..dc7c2bae8 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/SynchronousRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/SynchronousRequest.kt @@ -21,7 +21,7 @@ import com.malinskiy.adam.transport.Socket import com.malinskiy.adam.transport.withMaxPacketBuffer import kotlinx.coroutines.yield -abstract class SynchronousRequest(target: Target = NonSpecifiedTarget) : ComplexRequest(target), ResponseTransformer { +public abstract class SynchronousRequest(target: Target = NonSpecifiedTarget) : ComplexRequest(target), ResponseTransformer { override suspend fun readElement(socket: Socket): T { withMaxPacketBuffer { loop@ do { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/Target.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/Target.kt index 3d073c473..8f50f1ff2 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/Target.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/Target.kt @@ -16,8 +16,8 @@ package com.malinskiy.adam.request -sealed class Target { - abstract fun serialize(): String +public sealed class Target { + public abstract fun serialize(): String } /** @@ -25,8 +25,8 @@ sealed class Target { * interpreted as 'any single device or emulator connected to/running on * the host'. */ -object HostTarget : Target() { - override fun serialize() = "host:" +public object HostTarget : Target() { + override fun serialize(): String = "host:" } /** @@ -34,26 +34,26 @@ object HostTarget : Target() { * prefix can be used to indicate that the client is asking the ADB server * for information related to a specific device. */ -class SerialTarget(private val serial: String) : Target() { - override fun serialize() = "host-serial:$serial:" +public class SerialTarget(private val serial: String) : Target() { + override fun serialize(): String = "host-serial:$serial:" } /** * A variant of host-serial used to target the single USB device connected * to the host. This will fail if there is none or more than one. */ -object UsbTarget : Target() { - override fun serialize() = "host-usb:" +public object UsbTarget : Target() { + override fun serialize(): String = "host-usb:" } /** * A variant of host-serial used to target the single emulator instance * running on the host. This will fail if there is none or more than one. */ -object LocalTarget : Target() { - override fun serialize() = "host-local:" +public object LocalTarget : Target() { + override fun serialize(): String = "host-local:" } -object NonSpecifiedTarget : Target() { - override fun serialize() = "" +public object NonSpecifiedTarget : Target() { + override fun serialize(): String = "" } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/ValidationResponse.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/ValidationResponse.kt index befb299b8..8f8b74638 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/ValidationResponse.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/ValidationResponse.kt @@ -20,21 +20,21 @@ import com.malinskiy.adam.Const import java.io.File import java.util.* -data class ValidationResponse( - val success: Boolean, - val message: String? +public data class ValidationResponse( + public val success: Boolean, + public val message: String? ) { - companion object { - val Success = ValidationResponse(true, null) + public companion object { + public val Success: ValidationResponse = ValidationResponse(true, null) - fun missingFeature(feature: Feature) = "${feature.name} is not supported by device" - fun missingEitherFeature(vararg feature: Feature) = "Supported features must include either of ${feature.joinToString()}" - fun oneOfFilesShouldBe(extension: String) = "At least one of the files has to be an ${extension.uppercase(Locale.ENGLISH)} file" - fun packageShouldExist(file: File) = "Package ${file.absolutePath} doesn't exist" - fun packageShouldBeRegularFile(file: File) = "Package ${file.absolutePath} is not a regular file" - fun packageShouldBeSupportedExtension(file: File, supported: Set) = + public fun missingFeature(feature: Feature): String = "${feature.name} is not supported by device" + public fun missingEitherFeature(vararg feature: Feature): String = "Supported features must include either of ${feature.joinToString()}" + public fun oneOfFilesShouldBe(extension: String): String = "At least one of the files has to be an ${extension.uppercase(Locale.ENGLISH)} file" + public fun packageShouldExist(file: File): String = "Package ${file.absolutePath} doesn't exist" + public fun packageShouldBeRegularFile(file: File): String = "Package ${file.absolutePath} is not a regular file" + public fun packageShouldBeSupportedExtension(file: File, supported: Set): String = "Unsupported package extension ${file.extension}. Should be on of ${supported.joinToString()}}" - fun pathShouldNotBeLong() = "Remote path should be less that ${Const.MAX_REMOTE_PATH_LENGTH} bytes" + public fun pathShouldNotBeLong(): String = "Remote path should be less that ${Const.MAX_REMOTE_PATH_LENGTH} bytes" } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/abb/AbbExecRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/abb/AbbExecRequest.kt index 8e4841446..b158b4d28 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/abb/AbbExecRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/abb/AbbExecRequest.kt @@ -26,7 +26,7 @@ import com.malinskiy.adam.transport.Socket import com.malinskiy.adam.transport.withDefaultBuffer @Features(Feature.ABB_EXEC) -open class AbbExecRequest(private val args: List, private val supportedFeatures: List) : ComplexRequest() { +public open class AbbExecRequest(private val args: List, private val supportedFeatures: List) : ComplexRequest() { private val transformer = StringResponseTransformer() override suspend fun readElement(socket: Socket): String { @@ -36,7 +36,7 @@ open class AbbExecRequest(private val args: List, private val supportedF return transformer.transform() } - override fun serialize() = createBaseRequest("abb_exec:${args.joinToString(DELIMITER.toString())}") + override fun serialize(): ByteArray = createBaseRequest("abb_exec:${args.joinToString(DELIMITER.toString())}") override fun validate(): ValidationResponse { val response = super.validate() @@ -49,7 +49,7 @@ open class AbbExecRequest(private val args: List, private val supportedF } } - companion object { - const val DELIMITER = 0x00.toChar() + public companion object { + public const val DELIMITER: Char = 0x00.toChar() } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/abb/AbbRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/abb/AbbRequest.kt index 81b1ac5f6..d9edda918 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/abb/AbbRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/abb/AbbRequest.kt @@ -24,10 +24,10 @@ import com.malinskiy.adam.request.shell.v2.ShellCommandResult import com.malinskiy.adam.request.shell.v2.SyncShellCommandRequest @Features(Feature.ABB) -class AbbRequest(private val args: List, private val supportedFeatures: List) : +public class AbbRequest(private val args: List, private val supportedFeatures: List) : SyncShellCommandRequest("") { - override fun serialize() = createBaseRequest("abb:${args.joinToString(DELIMITER.toString())}") - override fun convertResult(response: ShellCommandResult) = response + override fun serialize(): ByteArray = createBaseRequest("abb:${args.joinToString(DELIMITER.toString())}") + override fun convertResult(response: ShellCommandResult): ShellCommandResult = response override fun validate(): ValidationResponse { val response = super.validate() return if (!response.success) { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/adbd/AdbdMode.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/adbd/AdbdMode.kt index 19008c6b7..9b671bff1 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/adbd/AdbdMode.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/adbd/AdbdMode.kt @@ -16,8 +16,8 @@ package com.malinskiy.adam.request.adbd -sealed class AdbdMode(val requestString: String) -object RootAdbdMode : AdbdMode("root:") -object UnrootAdbdMode : AdbdMode("unroot:") -object UsbAdbdMode : AdbdMode("usb:") -class TcpIpAdbdMode(port: Int) : AdbdMode("tcpip:$port") +public sealed class AdbdMode(public val requestString: String) +public object RootAdbdMode : AdbdMode("root:") +public object UnrootAdbdMode : AdbdMode("unroot:") +public object UsbAdbdMode : AdbdMode("usb:") +public class TcpIpAdbdMode(port: Int) : AdbdMode("tcpip:$port") diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/adbd/RestartAdbdRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/adbd/RestartAdbdRequest.kt index fef2aaabb..80ee1995d 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/adbd/RestartAdbdRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/adbd/RestartAdbdRequest.kt @@ -19,12 +19,12 @@ package com.malinskiy.adam.request.adbd import com.malinskiy.adam.request.SynchronousRequest import com.malinskiy.adam.request.transform.StringResponseTransformer -class RestartAdbdRequest(private val mode: AdbdMode) : SynchronousRequest() { +public class RestartAdbdRequest(private val mode: AdbdMode) : SynchronousRequest() { private val transformer = StringResponseTransformer() - override suspend fun process(bytes: ByteArray, offset: Int, limit: Int) = transformer.process(bytes, offset, limit) + override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = transformer.process(bytes, offset, limit) - override fun serialize() = createBaseRequest(mode.requestString) + override fun serialize(): ByteArray = createBaseRequest(mode.requestString) - override fun transform() = transformer.transform() + override fun transform(): String = transformer.transform() } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/device/AsyncDeviceMonitorRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/device/AsyncDeviceMonitorRequest.kt index f0f8604b3..28306653e 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/device/AsyncDeviceMonitorRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/device/AsyncDeviceMonitorRequest.kt @@ -22,7 +22,7 @@ import com.malinskiy.adam.request.HostTarget import com.malinskiy.adam.transport.Socket import kotlinx.coroutines.channels.SendChannel -class AsyncDeviceMonitorRequest : AsyncChannelRequest, Unit>(target = HostTarget, socketIdleTimeout = Long.MAX_VALUE) { +public class AsyncDeviceMonitorRequest : AsyncChannelRequest, Unit>(target = HostTarget, socketIdleTimeout = Long.MAX_VALUE) { override suspend fun readElement(socket: Socket, sendChannel: SendChannel>): Boolean { val data = socket.readProtocolString() @@ -41,6 +41,6 @@ class AsyncDeviceMonitorRequest : AsyncChannelRequest, Unit>(target return false } - override fun serialize() = createBaseRequest("track-devices") - override suspend fun writeElement(element: Unit, socket: Socket) = Unit + override fun serialize(): ByteArray = createBaseRequest("track-devices") + override suspend fun writeElement(element: Unit, socket: Socket): Unit = Unit } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/device/FetchDeviceFeaturesRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/device/FetchDeviceFeaturesRequest.kt index 57fdb8a1d..2276d3914 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/device/FetchDeviceFeaturesRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/device/FetchDeviceFeaturesRequest.kt @@ -22,9 +22,9 @@ import com.malinskiy.adam.request.Feature import com.malinskiy.adam.request.SerialTarget import com.malinskiy.adam.transport.Socket -class FetchDeviceFeaturesRequest(serial: String) : ComplexRequest>(target = SerialTarget(serial)) { +public class FetchDeviceFeaturesRequest(serial: String) : ComplexRequest>(target = SerialTarget(serial)) { - override fun serialize() = createBaseRequest("features") + override fun serialize(): ByteArray = createBaseRequest("features") override suspend fun readElement(socket: Socket): List { return socket.readProtocolString().split(',').mapNotNull { Feature.of(it) } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/device/ListDevicesRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/device/ListDevicesRequest.kt index fedbfb9fc..89413548e 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/device/ListDevicesRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/device/ListDevicesRequest.kt @@ -21,8 +21,8 @@ import com.malinskiy.adam.request.ComplexRequest import com.malinskiy.adam.request.HostTarget import com.malinskiy.adam.transport.Socket -class ListDevicesRequest : ComplexRequest>(target = HostTarget) { - override fun serialize() = createBaseRequest("devices") +public class ListDevicesRequest : ComplexRequest>(target = HostTarget) { + override fun serialize(): ByteArray = createBaseRequest("devices") override suspend fun readElement(socket: Socket): List { return socket.readProtocolString().lines() @@ -38,9 +38,9 @@ class ListDevicesRequest : ComplexRequest>(target = HostTarget) { } } -data class Device(val serial: String, val state: DeviceState) +public data class Device(public val serial: String, public val state: DeviceState) -enum class DeviceState { +public enum class DeviceState { OFFLINE, BOOTLOADER, DEVICE, @@ -53,8 +53,8 @@ enum class DeviceState { CONNECTING, UNKNOWN; - companion object { - fun from(value: String) = + public companion object { + public fun from(value: String): DeviceState = when (value) { "offline" -> OFFLINE "bootloader" -> BOOTLOADER diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/emu/EmulatorCommandRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/emu/EmulatorCommandRequest.kt index 5a58b04bb..46575f444 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/emu/EmulatorCommandRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/emu/EmulatorCommandRequest.kt @@ -38,12 +38,12 @@ import java.net.InetSocketAddress * @param cleanResponse by default all responses contain the emulator auth output that is unnecessary. If you want the output to include * everything the emulator returns - set this to false */ -class EmulatorCommandRequest( +public class EmulatorCommandRequest( private val cmd: String, - val address: InetSocketAddress, + public val address: InetSocketAddress, private val authToken: String? = null, private val cleanResponse: Boolean = true, - val idleTimeoutOverride: Long? = null + public val idleTimeoutOverride: Long? = null ) { private suspend fun readAuthToken(): String? { val authTokenFile = File(System.getProperty("user.home"), ".emulator_console_auth_token") @@ -59,7 +59,7 @@ class EmulatorCommandRequest( } } - suspend fun process(socket: Socket): String { + public suspend fun process(socket: Socket): String { val sessionBuilder = StringBuilder() val token = authToken ?: readAuthToken() ?: "" if (token.isNotEmpty()) { @@ -105,7 +105,7 @@ class EmulatorCommandRequest( } } - companion object { + public companion object { /** * Note: the following messages are expected to be quite stable from emulator. * Emulator console will send the following message upon connection: @@ -123,6 +123,6 @@ class EmulatorCommandRequest( * So we try to search and skip first two "OK\r\n", return the rest. * */ - const val OUTPUT_DELIMITER: String = "OK\r\n" + public const val OUTPUT_DELIMITER: String = "OK\r\n" } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/file/ListFilesRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/file/ListFilesRequest.kt index 9e5395496..aecc56199 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/file/ListFilesRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/file/ListFilesRequest.kt @@ -20,7 +20,7 @@ import com.malinskiy.adam.request.shell.v1.ShellCommandResult import com.malinskiy.adam.request.shell.v1.SyncShellCommandRequest -class ListFilesRequest(private val directory: String) : SyncShellCommandRequest>( +public class ListFilesRequest(private val directory: String) : SyncShellCommandRequest>( cmd = "ls -l $directory" ) { private val lslRegex: Regex = ("^([bcdlsp-][-r][-w][-xsS][-r][-w][-xsS][-r][-w][-xstST])\\s+" + //permissions @@ -83,7 +83,7 @@ class ListFilesRequest(private val directory: String) : SyncShellCommandRequest< } } -enum class AndroidFileType { +public enum class AndroidFileType { REGULAR_FILE, DIRECTORY, BLOCK_SPECIAL_FILE, @@ -106,15 +106,15 @@ enum class AndroidFileType { * @property type file's type * @property link if the file is a symbolic link, this field is what the link points to */ -data class AndroidFile( - val permissions: String, - val owner: String, - val group: String, - val date: String, - val time: String, - val name: String, - val directory: String, - val size: Long, - val type: AndroidFileType, - val link: String? = null +public data class AndroidFile( + public val permissions: String, + public val owner: String, + public val group: String, + public val date: String, + public val time: String, + public val name: String, + public val directory: String, + public val size: Long, + public val type: AndroidFileType, + public val link: String? = null ) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/ListPortForwardsRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/ListPortForwardsRequest.kt index ace551099..30b1adca1 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/ListPortForwardsRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/ListPortForwardsRequest.kt @@ -21,7 +21,7 @@ import com.malinskiy.adam.request.ComplexRequest import com.malinskiy.adam.request.SerialTarget import com.malinskiy.adam.transport.Socket -class ListPortForwardsRequest(serial: String) : ComplexRequest>(target = SerialTarget(serial)) { +public class ListPortForwardsRequest(serial: String) : ComplexRequest>(target = SerialTarget(serial)) { override suspend fun readElement(socket: Socket): List { return socket.readProtocolString().lines().mapNotNull { line -> if (line.isNotEmpty()) { @@ -37,6 +37,6 @@ class ListPortForwardsRequest(serial: String) : ComplexRequest(target = SerialTarget(serial)) { - override fun serialize() = + override fun serialize(): ByteArray = createBaseRequest("forward${mode.value}:${local.toSpec()};${remote.toSpec()}") override suspend fun readElement(socket: Socket): Int? { @@ -47,7 +47,7 @@ class PortForwardRequest( } } -enum class PortForwardingMode(val value: String) { +public enum class PortForwardingMode(public val value: String) { DEFAULT(""), NO_REBIND(":norebind") } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/PortForwardingRule.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/PortForwardingRule.kt index dbb93e424..e7fdae394 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/PortForwardingRule.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/PortForwardingRule.kt @@ -16,8 +16,8 @@ package com.malinskiy.adam.request.forwarding -data class PortForwardingRule( - val serial: String, - val localSpec: LocalPortSpec, - val remoteSpec: RemotePortSpec +public data class PortForwardingRule( + public val serial: String, + public val localSpec: LocalPortSpec, + public val remoteSpec: RemotePortSpec ) \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/RemotePortSpec.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/RemotePortSpec.kt index 11fa53407..621944718 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/RemotePortSpec.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/RemotePortSpec.kt @@ -18,11 +18,11 @@ package com.malinskiy.adam.request.forwarding import com.malinskiy.adam.exception.UnsupportedForwardingSpecException -sealed class RemotePortSpec { - abstract fun toSpec(): String +public sealed class RemotePortSpec { + public abstract fun toSpec(): String - companion object { - fun parse(value: String): RemotePortSpec { + public companion object { + public fun parse(value: String): RemotePortSpec { val split = value.split(':') val type = split[0] return when (type) { @@ -38,26 +38,26 @@ sealed class RemotePortSpec { } } -data class RemoteTcpPortSpec(val port: Int) : RemotePortSpec() { - override fun toSpec() = "tcp:$port" +public data class RemoteTcpPortSpec(public val port: Int) : RemotePortSpec() { + override fun toSpec(): String = "tcp:$port" } -data class RemoteAbstractPortSpec(val unixDomainSocketName: String) : RemotePortSpec() { - override fun toSpec() = "localabstract:$unixDomainSocketName" +public data class RemoteAbstractPortSpec(public val unixDomainSocketName: String) : RemotePortSpec() { + override fun toSpec(): String = "localabstract:$unixDomainSocketName" } -data class RemoteReservedPortSpec(val unixDomainSocketName: String) : RemotePortSpec() { - override fun toSpec() = "localreserved:$unixDomainSocketName" +public data class RemoteReservedPortSpec(public val unixDomainSocketName: String) : RemotePortSpec() { + override fun toSpec(): String = "localreserved:$unixDomainSocketName" } -data class RemoteFilesystemPortSpec(val unixDomainSocketName: String) : RemotePortSpec() { - override fun toSpec() = "localfilesystem:$unixDomainSocketName" +public data class RemoteFilesystemPortSpec(public val unixDomainSocketName: String) : RemotePortSpec() { + override fun toSpec(): String = "localfilesystem:$unixDomainSocketName" } -data class RemoteDevPortSpec(val charDeviceName: String) : RemotePortSpec() { - override fun toSpec() = "dev:$charDeviceName" +public data class RemoteDevPortSpec(public val charDeviceName: String) : RemotePortSpec() { + override fun toSpec(): String = "dev:$charDeviceName" } -data class JDWPPortSpec(val processId: Int) : RemotePortSpec() { - override fun toSpec() = "jdwp:$processId" +public data class JDWPPortSpec(public val processId: Int) : RemotePortSpec() { + override fun toSpec(): String = "jdwp:$processId" } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/RemoveAllPortForwardsRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/RemoveAllPortForwardsRequest.kt index fe59a0a4c..b28b9bddd 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/RemoveAllPortForwardsRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/RemoveAllPortForwardsRequest.kt @@ -19,10 +19,10 @@ package com.malinskiy.adam.request.forwarding import com.malinskiy.adam.request.SerialTarget import com.malinskiy.adam.request.SynchronousRequest -class RemoveAllPortForwardsRequest(serial: String) : SynchronousRequest(target = SerialTarget(serial)) { - override fun serialize() = createBaseRequest("killforward-all") +public class RemoveAllPortForwardsRequest(serial: String) : SynchronousRequest(target = SerialTarget(serial)) { + override fun serialize(): ByteArray = createBaseRequest("killforward-all") - override suspend fun process(bytes: ByteArray, offset: Int, limit: Int) = Unit + override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = Unit - override fun transform() = Unit + override fun transform(): Unit = Unit } \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/RemovePortForwardRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/RemovePortForwardRequest.kt index d53a4ac4d..82d48046b 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/RemovePortForwardRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/RemovePortForwardRequest.kt @@ -19,14 +19,14 @@ package com.malinskiy.adam.request.forwarding import com.malinskiy.adam.request.SerialTarget import com.malinskiy.adam.request.SynchronousRequest -class RemovePortForwardRequest( +public class RemovePortForwardRequest( private val local: LocalTcpPortSpec, serial: String ) : SynchronousRequest(target = SerialTarget(serial)) { - override fun serialize() = + override fun serialize(): ByteArray = createBaseRequest("killforward:${local.toSpec()}") - override suspend fun process(bytes: ByteArray, offset: Int, limit: Int) = Unit + override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = Unit - override fun transform() = Unit + override fun transform(): Unit = Unit } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/BufferedImageScreenCaptureAdapter.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/BufferedImageScreenCaptureAdapter.kt index 2ef7d69fe..1b267f9a1 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/BufferedImageScreenCaptureAdapter.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/BufferedImageScreenCaptureAdapter.kt @@ -21,7 +21,7 @@ import com.malinskiy.adam.transport.Socket import java.awt.image.BufferedImage import java.nio.ByteBuffer -class BufferedImageScreenCaptureAdapter( +public class BufferedImageScreenCaptureAdapter( private var recycledImage: BufferedImage? = null, buffer: ByteBuffer? = null, colorModelFactory: ColorModelFactory = ColorModelFactory() diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/Color.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/Color.kt index 161b7bd15..04eaaecd5 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/Color.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/Color.kt @@ -18,9 +18,9 @@ package com.malinskiy.adam.request.framebuffer import kotlin.math.roundToInt -object Color { - object RGB565_2BYTE { - fun toARGB8888_INT(first: Byte, second: Byte): Int { +public object Color { + public object RGB565_2BYTE { + public fun toARGB8888_INT(first: Byte, second: Byte): Int { var value = first.toInt() and 0x00FF value = value or (second.toInt() shl 8 and 0x0FF00) // Multiply by 255/31 to convert from 5 bits (31 max) to 8 bits (255) @@ -33,8 +33,8 @@ object Color { } } - object ARGB_INT { - fun toARGB8888_INT( + public object ARGB_INT { + public fun toARGB8888_INT( value: Int, redOffset: Int, redLength: Int, @@ -53,7 +53,7 @@ object Color { return a shl 24 or (r shl 16) or (g shl 8) or b } - fun toBGR_3BYTE( + public fun toBGR_3BYTE( value: Int, redOffset: Int, redLength: Int, diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ColorModelFactory.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ColorModelFactory.kt index c7d5f532a..c9a1865d8 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ColorModelFactory.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ColorModelFactory.kt @@ -26,10 +26,10 @@ import java.awt.image.DataBuffer import java.awt.image.DirectColorModel import java.io.IOException -class ColorModelFactory { +public class ColorModelFactory { private val cache = mutableMapOf() - fun get(profileName: String, type: Int): ColorModel { + public fun get(profileName: String, type: Int): ColorModel { cache[profileName]?.let { return it } synchronized(cache) { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ColorSpace.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ColorSpace.kt index 7df8f0f3a..50e97ad00 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ColorSpace.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ColorSpace.kt @@ -16,19 +16,19 @@ package com.malinskiy.adam.request.framebuffer -enum class ColorSpace { +public enum class ColorSpace { UNKNOWN, SRGB, P3; - fun getProfileName(): String? = when (this) { + public fun getProfileName(): String? = when (this) { UNKNOWN -> null SRGB -> "sRGB.icc" P3 -> "DisplayP3.icc" } - companion object { - fun from(value: Int) = when (value) { + public companion object { + public fun from(value: Int): ColorSpace = when (value) { 1 -> SRGB 2 -> P3 else -> UNKNOWN diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/RawImage.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/RawImage.kt index d9b5833ec..061dee892 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/RawImage.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/RawImage.kt @@ -19,24 +19,24 @@ package com.malinskiy.adam.request.framebuffer import java.awt.image.BufferedImage -data class RawImage( - val version: Int, - val bitsPerPixel: Int, - val colorSpace: ColorSpace? = null, - val size: Int, - val width: Int, - val height: Int, - val redOffset: Int, - val redLength: Int, - val blueOffset: Int, - val blueLength: Int, - val greenOffset: Int, - val greenLength: Int, - val alphaOffset: Int, - val alphaLength: Int, - val buffer: ByteArray +public data class RawImage( + public val version: Int, + public val bitsPerPixel: Int, + public val colorSpace: ColorSpace? = null, + public val size: Int, + public val width: Int, + public val height: Int, + public val redOffset: Int, + public val redLength: Int, + public val blueOffset: Int, + public val blueLength: Int, + public val greenOffset: Int, + public val greenLength: Int, + public val alphaOffset: Int, + public val alphaLength: Int, + public val buffer: ByteArray ) { - fun getARGB(index: Int): Int { + public fun getARGB(index: Int): Int { return when (bitsPerPixel) { 16 -> { Color.RGB565_2BYTE.toARGB8888_INT(buffer[index], buffer[index + 1]) @@ -67,7 +67,7 @@ data class RawImage( /** * @return TYPE_INT_ARGB buffered image */ - fun toBufferedImage(): BufferedImage { + public fun toBufferedImage(): BufferedImage { val bufferedImage = when (val profileName = colorSpace?.getProfileName()) { null -> { BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/RawImageScreenCaptureAdapter.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/RawImageScreenCaptureAdapter.kt index 291a31ffc..46f828a41 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/RawImageScreenCaptureAdapter.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/RawImageScreenCaptureAdapter.kt @@ -19,7 +19,7 @@ package com.malinskiy.adam.request.framebuffer import com.malinskiy.adam.transport.Socket import java.nio.ByteBuffer -class RawImageScreenCaptureAdapter(buffer: ByteBuffer? = null) : ScreenCaptureAdapter(buffer = buffer) { +public class RawImageScreenCaptureAdapter(buffer: ByteBuffer? = null) : ScreenCaptureAdapter(buffer = buffer) { override suspend fun process( version: Int, diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureAdapter.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureAdapter.kt index 07e000aa1..9d47e8bed 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureAdapter.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureAdapter.kt @@ -27,11 +27,11 @@ import java.nio.ByteBuffer * @param buffer consider reusing the buffer between screencapture requests to reduce heap memory pressure * @param colorModelFactory reuse the color models required for image conversion */ -abstract class ScreenCaptureAdapter( +public abstract class ScreenCaptureAdapter( private var buffer: ByteBuffer? = null, protected val colorModelFactory: ColorModelFactory = ColorModelFactory() ) { - suspend fun read(socket: Socket, size: Int): ByteBuffer { + public suspend fun read(socket: Socket, size: Int): ByteBuffer { val localBuffer = buffer val imageBuffer = if (localBuffer != null && localBuffer.capacity() == size) { @@ -46,7 +46,7 @@ abstract class ScreenCaptureAdapter( return imageBuffer } - abstract suspend fun process( + public abstract suspend fun process( version: Int, bitsPerPixel: Int, size: Int, diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequest.kt index 024b157e2..d7e441c80 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequest.kt @@ -26,7 +26,7 @@ import com.malinskiy.adam.transport.Socket import com.malinskiy.adam.transport.withDefaultBuffer import java.nio.ByteOrder -class ScreenCaptureRequest(private val adapter: ScreenCaptureAdapter) : ComplexRequest() { +public class ScreenCaptureRequest(private val adapter: ScreenCaptureAdapter) : ComplexRequest() { override suspend fun readElement(socket: Socket): T { withDefaultBuffer { compatLimit(4) @@ -106,5 +106,5 @@ class ScreenCaptureRequest(private val adapter: ScreenCaptureAdapter) : Co } } - override fun serialize() = createBaseRequest("framebuffer:") + override fun serialize(): ByteArray = createBaseRequest("framebuffer:") } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/ChanneledLogcatRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/ChanneledLogcatRequest.kt index 5ba239e77..f375bc475 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/ChanneledLogcatRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/ChanneledLogcatRequest.kt @@ -18,7 +18,7 @@ package com.malinskiy.adam.request.logcat import com.malinskiy.adam.request.shell.v1.ChanneledShellCommandRequest -class ChanneledLogcatRequest( +public class ChanneledLogcatRequest( since: LogcatSinceFormat? = null, modes: List = listOf(LogcatReadMode.long), buffers: List = emptyList(), @@ -43,7 +43,7 @@ class ChanneledLogcatRequest( socketIdleTimeout = Long.MAX_VALUE, ) -enum class LogcatReadMode { +public enum class LogcatReadMode { brief, long, process, @@ -84,7 +84,7 @@ enum class LogcatReadMode { zone } -enum class LogcatBuffer { +public enum class LogcatBuffer { //View the buffer that contains radio/telephony related messages radio, @@ -107,7 +107,7 @@ enum class LogcatBuffer { default } -enum class LogcatVerbosityLevel { +public enum class LogcatVerbosityLevel { V, D, I, @@ -117,6 +117,6 @@ enum class LogcatVerbosityLevel { S } -data class LogcatFilterSpec(val tag: String, val level: LogcatVerbosityLevel) +public data class LogcatFilterSpec(public val tag: String, public val level: LogcatVerbosityLevel) -val SupressAll = LogcatFilterSpec("*", LogcatVerbosityLevel.S) +public val SupressAll: LogcatFilterSpec = LogcatFilterSpec("*", LogcatVerbosityLevel.S) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/LogcatSinceFormat.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/LogcatSinceFormat.kt index fbce4f2de..3bd7d170b 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/LogcatSinceFormat.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/LogcatSinceFormat.kt @@ -25,16 +25,16 @@ private val sinceFormatter = DateTimeFormatter.ofPattern("MM-dd HH:mm:ss.SSS") private val sinceYearFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS") -sealed class LogcatSinceFormat(val text: String) { +public sealed class LogcatSinceFormat(public val text: String) { // It formats with 'MM-dd HH:mm:ss.SSS' - class DateString(instant: Instant, timezone: String) : + public class DateString(instant: Instant, timezone: String) : LogcatSinceFormat("'${sinceFormatter.withZone(TimeZone.getTimeZone(timezone).toZoneId()).format(instant)}'") // It formats with 'yyyy-MM-dd HH:mm:ss.SSS' - class DateStringYear(instant: Instant, timezone: String) : + public class DateStringYear(instant: Instant, timezone: String) : LogcatSinceFormat("'${sinceYearFormatter.withZone(TimeZone.getTimeZone(timezone).toZoneId()).format(instant)}'") // It formats with 'SSS.0' - class TimeStamp(instant: Instant) : + public class TimeStamp(instant: Instant) : LogcatSinceFormat("${instant.toEpochMilli()}.0") } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/SyncLogcatRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/SyncLogcatRequest.kt index 6b16383aa..758f76b54 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/SyncLogcatRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/SyncLogcatRequest.kt @@ -20,7 +20,7 @@ import com.malinskiy.adam.request.shell.v1.ShellCommandResult import com.malinskiy.adam.request.shell.v1.SyncShellCommandRequest import java.time.Instant -class SyncLogcatRequest( +public class SyncLogcatRequest( since: LogcatSinceFormat? = null, modes: List = listOf(LogcatReadMode.long), buffers: List = listOf(LogcatBuffer.default), @@ -40,5 +40,5 @@ class SyncLogcatRequest( " ${filters.joinToString(separator = " ") { "${it.tag}:${it.level.name}" }}" .trimEnd() ) { - override fun convertResult(response: ShellCommandResult) = response.output + override fun convertResult(response: ShellCommandResult): String = response.output } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/ListMdnsServicesRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/ListMdnsServicesRequest.kt index 287090be3..e7319afb6 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/ListMdnsServicesRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/ListMdnsServicesRequest.kt @@ -21,7 +21,7 @@ import com.malinskiy.adam.request.ComplexRequest import com.malinskiy.adam.request.HostTarget import com.malinskiy.adam.transport.Socket -class ListMdnsServicesRequest : ComplexRequest>(target = HostTarget) { +public class ListMdnsServicesRequest : ComplexRequest>(target = HostTarget) { override suspend fun readElement(socket: Socket): List { return socket.readProtocolString().lines() @@ -36,5 +36,5 @@ class ListMdnsServicesRequest : ComplexRequest>(target = HostT } } - override fun serialize() = createBaseRequest("mdns:services") + override fun serialize(): ByteArray = createBaseRequest("mdns:services") } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsCheckRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsCheckRequest.kt index cb479f710..22893a798 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsCheckRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsCheckRequest.kt @@ -24,7 +24,7 @@ import com.malinskiy.adam.transport.Socket /** * check if mdns discovery is available */ -class MdnsCheckRequest : ComplexRequest(target = HostTarget) { +public class MdnsCheckRequest : ComplexRequest(target = HostTarget) { override suspend fun readElement(socket: Socket): MdnsStatus { val string = socket.readProtocolString() return if (string.contains("mdns daemon unavailable")) { @@ -35,5 +35,5 @@ class MdnsCheckRequest : ComplexRequest(target = HostTarget) { } } - override fun serialize() = createBaseRequest("mdns:check") + override fun serialize(): ByteArray = createBaseRequest("mdns:check") } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsService.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsService.kt index 08e52a1e7..869aeb393 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsService.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsService.kt @@ -16,8 +16,8 @@ package com.malinskiy.adam.request.mdns -data class MdnsService( - val name: String, - val serviceType: String, - val url: String +public data class MdnsService( + public val name: String, + public val serviceType: String, + public val url: String ) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsStatus.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsStatus.kt index 37f97411f..be63afecf 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsStatus.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsStatus.kt @@ -16,7 +16,7 @@ package com.malinskiy.adam.request.mdns -data class MdnsStatus( - val available: Boolean, - val version: String? = null +public data class MdnsStatus( + public val available: Boolean, + public val version: String? = null ) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ConnectDeviceRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ConnectDeviceRequest.kt index 026219b4e..71ac6cbd6 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ConnectDeviceRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ConnectDeviceRequest.kt @@ -24,12 +24,12 @@ import com.malinskiy.adam.transport.Socket /** * Connects a remote device */ -class ConnectDeviceRequest( +public class ConnectDeviceRequest( private val host: String, private val port: Int = 5555 ) : ComplexRequest(target = HostTarget) { - override fun serialize() = createBaseRequest("connect:$host:$port") + override fun serialize(): ByteArray = createBaseRequest("connect:$host:$port") - override suspend fun readElement(socket: Socket) = socket.readProtocolString() + override suspend fun readElement(socket: Socket): String = socket.readProtocolString() } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/DisconnectDeviceRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/DisconnectDeviceRequest.kt index ee396acb4..765cd6296 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/DisconnectDeviceRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/DisconnectDeviceRequest.kt @@ -27,12 +27,12 @@ import com.malinskiy.adam.transport.Socket * @param host target device that will be disconnected. if null then disconnects all devices * @param port target device's port. can be null in case of locally connected devices, i.e. physical phones and emulators */ -class DisconnectDeviceRequest( +public class DisconnectDeviceRequest( private val host: String? = null, private val port: Int? = 5555 ) : ComplexRequest(target = HostTarget) { - override fun serialize() = createBaseRequest( + override fun serialize(): ByteArray = createBaseRequest( "disconnect:${ if (host == null) { "" @@ -44,5 +44,5 @@ class DisconnectDeviceRequest( }" ) - override suspend fun readElement(socket: Socket) = socket.readProtocolString() + override suspend fun readElement(socket: Socket): String = socket.readProtocolString() } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ExecInRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ExecInRequest.kt index ae3f11d22..3dc603b31 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ExecInRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ExecInRequest.kt @@ -26,7 +26,7 @@ import kotlinx.coroutines.channels.SendChannel /** * Executes the command and provides the channel as the input to the command. Does not return anything */ -class ExecInRequest( +public class ExecInRequest( private val cmd: String, private val channel: ReceiveChannel, private val sizeChannel: SendChannel, @@ -51,5 +51,5 @@ class ExecInRequest( socket.readStatus() } - override fun serialize() = createBaseRequest("exec:$cmd") + override fun serialize(): ByteArray = createBaseRequest("exec:$cmd") } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/FetchHostFeaturesRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/FetchHostFeaturesRequest.kt index b91a614de..d9f0122f2 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/FetchHostFeaturesRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/FetchHostFeaturesRequest.kt @@ -22,9 +22,9 @@ import com.malinskiy.adam.request.Feature import com.malinskiy.adam.request.HostTarget import com.malinskiy.adam.transport.Socket -class FetchHostFeaturesRequest : ComplexRequest>(target = HostTarget) { +public class FetchHostFeaturesRequest : ComplexRequest>(target = HostTarget) { - override fun serialize() = createBaseRequest("host-features") + override fun serialize(): ByteArray = createBaseRequest("host-features") override suspend fun readElement(socket: Socket): List { return socket.readProtocolString().split(',').mapNotNull { Feature.of(it) } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/GetAdbServerVersionRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/GetAdbServerVersionRequest.kt index e27ffb756..f0cd85e68 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/GetAdbServerVersionRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/GetAdbServerVersionRequest.kt @@ -25,11 +25,11 @@ import com.malinskiy.adam.transport.Socket /** * @see https://android.googlesource.com/platform/system/core/+/refs/heads/master/adb/adb.h#62 */ -class GetAdbServerVersionRequest : ComplexRequest(target = HostTarget) { +public class GetAdbServerVersionRequest : ComplexRequest(target = HostTarget) { override suspend fun readElement(socket: Socket): Int { val version = socket.readOptionalProtocolString() return version?.toIntOrNull(radix = 16) ?: throw RequestRejectedException("Empty/corrupt response") } - override fun serialize() = createBaseRequest("version") + override fun serialize(): ByteArray = createBaseRequest("version") } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/KillAdbRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/KillAdbRequest.kt index e71dd4946..c8450b1f5 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/KillAdbRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/KillAdbRequest.kt @@ -19,10 +19,10 @@ package com.malinskiy.adam.request.misc import com.malinskiy.adam.request.HostTarget import com.malinskiy.adam.request.SynchronousRequest -class KillAdbRequest : SynchronousRequest(target = HostTarget) { - override fun serialize() = createBaseRequest("kill") +public class KillAdbRequest : SynchronousRequest(target = HostTarget) { + override fun serialize(): ByteArray = createBaseRequest("kill") - override suspend fun process(bytes: ByteArray, offset: Int, limit: Int) = Unit + override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = Unit - override fun transform() = Unit + override fun transform(): Unit = Unit } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/PairDeviceRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/PairDeviceRequest.kt index 40b23e9d5..150bef4fe 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/PairDeviceRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/PairDeviceRequest.kt @@ -27,12 +27,12 @@ import com.malinskiy.adam.transport.Socket * * @param url target device in the form of host[:port], port is optional */ -class PairDeviceRequest( +public class PairDeviceRequest( private val url: String, private val pairingCode: String ) : ComplexRequest(target = HostTarget) { - override suspend fun readElement(socket: Socket) = socket.readProtocolString() + override suspend fun readElement(socket: Socket): String = socket.readProtocolString() - override fun serialize() = createBaseRequest("pair:$pairingCode:$url") + override fun serialize(): ByteArray = createBaseRequest("pair:$pairingCode:$url") } \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/RebootRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/RebootRequest.kt index ce91140ab..27d5bc2e5 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/RebootRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/RebootRequest.kt @@ -18,15 +18,15 @@ package com.malinskiy.adam.request.misc import com.malinskiy.adam.request.SynchronousRequest -class RebootRequest(private val mode: RebootMode = RebootMode.DEFAULT) : SynchronousRequest() { - override suspend fun process(bytes: ByteArray, offset: Int, limit: Int) = Unit +public class RebootRequest(private val mode: RebootMode = RebootMode.DEFAULT) : SynchronousRequest() { + override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = Unit - override fun serialize() = createBaseRequest("reboot:${mode.value}") + override fun serialize(): ByteArray = createBaseRequest("reboot:${mode.value}") - override fun transform() = Unit + override fun transform(): Unit = Unit } -enum class RebootMode(val value: String) { +public enum class RebootMode(public val value: String) { DEFAULT(""), RECOVERY("recovery"), BOOTLOADER("bootloader"), diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ReconnectRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ReconnectRequest.kt index 1d5f906f2..8757b0ef9 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ReconnectRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ReconnectRequest.kt @@ -35,7 +35,7 @@ import com.malinskiy.adam.transport.withDefaultBuffer * * @param reconnectTarget default behaviour depends on the target serial that will be specified during execution */ -class ReconnectRequest( +public class ReconnectRequest( private val reconnectTarget: ReconnectTarget? = null, target: Target = NonSpecifiedTarget ) : ComplexRequest(target = target) { @@ -58,18 +58,18 @@ class ReconnectRequest( } } - override fun serialize() = when (reconnectTarget) { + override fun serialize(): ByteArray = when (reconnectTarget) { null -> createBaseRequest("reconnect") Device -> createBaseRequest("reconnect") Offline -> createBaseRequest("reconnect-offline") } - companion object { + public companion object { /** * For some reason this done is lowercase and doesn't use the DONE message as everything else * see daemon/services.cpp#reconnect_service */ - val done = byteArrayOf( + public val done: ByteArray = byteArrayOf( 'd'.code.toByte(), 'o'.code.toByte(), 'n'.code.toByte(), @@ -78,10 +78,10 @@ class ReconnectRequest( } } -sealed class ReconnectTarget -object Device : ReconnectTarget() +public sealed class ReconnectTarget +public object Device : ReconnectTarget() /** * Only supports host target */ -object Offline : ReconnectTarget() +public object Offline : ReconnectTarget() diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/RemountPartitionsRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/RemountPartitionsRequest.kt index f7b52d591..bf4c9080f 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/RemountPartitionsRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/RemountPartitionsRequest.kt @@ -19,17 +19,17 @@ package com.malinskiy.adam.request.misc import com.malinskiy.adam.request.SynchronousRequest import com.malinskiy.adam.request.transform.StringResponseTransformer -class RemountPartitionsRequest(private val autoReboot: Boolean = false) : SynchronousRequest() { +public class RemountPartitionsRequest(private val autoReboot: Boolean = false) : SynchronousRequest() { private val transformer = StringResponseTransformer() - override suspend fun process(bytes: ByteArray, offset: Int, limit: Int) = transformer.process(bytes, offset, limit) + override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = transformer.process(bytes, offset, limit) - override fun serialize() = createBaseRequest( + override fun serialize(): ByteArray = createBaseRequest( when (autoReboot) { true -> "remount:-R" false -> "remount:" } ) - override fun transform() = transformer.transform() + override fun transform(): String = transformer.transform() } \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/SetDeviceRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/SetDeviceRequest.kt index c7a4c600c..4e9afc723 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/SetDeviceRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/SetDeviceRequest.kt @@ -19,6 +19,6 @@ package com.malinskiy.adam.request.misc import com.malinskiy.adam.request.HostTarget import com.malinskiy.adam.request.Request -class SetDeviceRequest(private val serial: String) : Request(target = HostTarget) { - override fun serialize() = createBaseRequest("transport:$serial") +public class SetDeviceRequest(private val serial: String) : Request(target = HostTarget) { + override fun serialize(): ByteArray = createBaseRequest("transport:$serial") } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/AtomicInstallPackageRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/AtomicInstallPackageRequest.kt index 17cc18b9a..398c8869e 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/AtomicInstallPackageRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/AtomicInstallPackageRequest.kt @@ -46,14 +46,14 @@ import kotlin.coroutines.CoroutineContext * @see com.malinskiy.adam.request.device.FetchDeviceFeaturesRequest */ @Features(Feature.CMD, Feature.ABB_EXEC, Feature.APEX) -class AtomicInstallPackageRequest( +public class AtomicInstallPackageRequest( private val pkgList: List, private val supportedFeatures: List, private val reinstall: Boolean, private val extraArgs: List = emptyList(), - val coroutineContext: CoroutineContext = Dispatchers.IO + public val coroutineContext: CoroutineContext = Dispatchers.IO ) : AccumulatingMultiRequest() { - override suspend fun execute(androidDebugBridgeClient: AndroidDebugBridgeClient, serial: String?) = with(androidDebugBridgeClient) { + override suspend fun execute(androidDebugBridgeClient: AndroidDebugBridgeClient, serial: String?): String = with(androidDebugBridgeClient) { val (parentSessionId, output) = execute(CreateMultiPackageSessionRequest(pkgList, supportedFeatures, reinstall, extraArgs), serial) output.addToResponse() diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/InstallRemotePackageRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/InstallRemotePackageRequest.kt index 7a572f662..d3529c727 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/InstallRemotePackageRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/InstallRemotePackageRequest.kt @@ -19,7 +19,7 @@ package com.malinskiy.adam.request.pkg import com.malinskiy.adam.request.ValidationResponse import com.malinskiy.adam.request.shell.v1.ShellCommandRequest -class InstallRemotePackageRequest( +public class InstallRemotePackageRequest( private val absoluteRemoteFilePath: String, reinstall: Boolean, extraArgs: List = emptyList() diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/InstallSplitPackageRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/InstallSplitPackageRequest.kt index 032488407..d235474e5 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/InstallSplitPackageRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/InstallSplitPackageRequest.kt @@ -49,19 +49,19 @@ import kotlin.coroutines.CoroutineContext * If both CMD and ABB_EXEC are missing, falls back to exec:pm */ @Features(Feature.CMD, Feature.ABB_EXEC) -class InstallSplitPackageRequest( +public class InstallSplitPackageRequest( private val pkg: ApkSplitInstallationPackage, private val supportedFeatures: List, private val reinstall: Boolean, private val extraArgs: List = emptyList(), - val coroutineContext: CoroutineContext = Dispatchers.IO + public val coroutineContext: CoroutineContext = Dispatchers.IO ) : AccumulatingMultiRequest() { private val totalSize: Long by lazy { pkg.fileList.sumOf { it.length() } } - override suspend fun execute(androidDebugBridgeClient: AndroidDebugBridgeClient, serial: String?) = with(androidDebugBridgeClient) { + override suspend fun execute(androidDebugBridgeClient: AndroidDebugBridgeClient, serial: String?): String = with(androidDebugBridgeClient) { val (sessionId, output) = execute( CreateIndividualPackageSessionRequest( pkg, @@ -123,7 +123,7 @@ class InstallSplitPackageRequest( } } - companion object { - val SUPPORTED_EXTENSIONS = setOf("apk", "dm", "fsv_sig") + public companion object { + public val SUPPORTED_EXTENSIONS: Set = setOf("apk", "dm", "fsv_sig") } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/LegacySideloadRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/LegacySideloadRequest.kt index aff540a1c..48f725778 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/LegacySideloadRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/LegacySideloadRequest.kt @@ -30,9 +30,9 @@ import kotlin.coroutines.CoroutineContext /** * pre-KitKat */ -class LegacySideloadRequest( +public class LegacySideloadRequest( private val pkg: File, - val coroutineContext: CoroutineContext = Dispatchers.IO + public val coroutineContext: CoroutineContext = Dispatchers.IO ) : ComplexRequest() { override fun validate(): ValidationResponse { val message = @@ -47,7 +47,7 @@ class LegacySideloadRequest( return ValidationResponse(message == null, message) } - override fun serialize() = createBaseRequest("sideload:${pkg.length()}") + override fun serialize(): ByteArray = createBaseRequest("sideload:${pkg.length()}") override suspend fun readElement(socket: Socket): Boolean { AsyncFileReader(pkg, coroutineContext = coroutineContext).use { reader -> diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/PmListRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/PmListRequest.kt index dd1fa85bf..c94e85e61 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/PmListRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/PmListRequest.kt @@ -19,7 +19,7 @@ package com.malinskiy.adam.request.pkg import com.malinskiy.adam.request.shell.v1.ShellCommandResult import com.malinskiy.adam.request.shell.v1.SyncShellCommandRequest -class PmListRequest(private val includePath: Boolean = false) : SyncShellCommandRequest>( +public class PmListRequest(private val includePath: Boolean = false) : SyncShellCommandRequest>( cmd = StringBuilder().apply { append("pm list packages") @@ -48,7 +48,7 @@ class PmListRequest(private val includePath: Boolean = false) : SyncShellCommand } } -data class Package( - val name: String, - val path: String? = null +public data class Package( + public val name: String, + public val path: String? = null ) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/SideloadRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/SideloadRequest.kt index e0565d5ce..62586a47d 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/SideloadRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/SideloadRequest.kt @@ -24,11 +24,11 @@ import com.malinskiy.adam.transport.AdamMaxFilePacketPool import com.malinskiy.adam.transport.Socket import java.io.File -class SideloadRequest( +public class SideloadRequest( private val pkg: File, ) : ComplexRequest() { private val blockSize: Int = Const.MAX_FILE_PACKET_LENGTH - val buffer = ByteArray(blockSize) + public val buffer: ByteArray = ByteArray(blockSize) override suspend fun readElement(socket: Socket): Boolean { var reader: AsyncFileReader? = null @@ -90,5 +90,5 @@ class SideloadRequest( return ValidationResponse(message == null, message) } - override fun serialize() = createBaseRequest("sideload-host:${pkg.length()}:${blockSize}") + override fun serialize(): ByteArray = createBaseRequest("sideload-host:${pkg.length()}:${blockSize}") } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/StreamingPackageInstallRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/StreamingPackageInstallRequest.kt index ad688c51d..c1180b323 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/StreamingPackageInstallRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/StreamingPackageInstallRequest.kt @@ -40,12 +40,12 @@ import kotlin.coroutines.CoroutineContext * @see com.malinskiy.adam.request.device.FetchDeviceFeaturesRequest */ @Features(Feature.CMD, Feature.ABB_EXEC, Feature.APEX) -class StreamingPackageInstallRequest( +public class StreamingPackageInstallRequest( private val pkg: File, private val supportedFeatures: List, private val reinstall: Boolean, private val extraArgs: List = emptyList(), - val coroutineContext: CoroutineContext = Dispatchers.IO + public val coroutineContext: CoroutineContext = Dispatchers.IO ) : ComplexRequest() { private val transformer = StringResponseTransformer() @@ -124,9 +124,9 @@ class StreamingPackageInstallRequest( return StreamingPackageInstallResult(output, success) } - companion object { - val SUPPORTED_EXTENSIONS = setOf("apk", "apex") + public companion object { + public val SUPPORTED_EXTENSIONS: Set = setOf("apk", "apex") } } -data class StreamingPackageInstallResult(val output: String, val success: Boolean) +public data class StreamingPackageInstallResult(public val output: String, public val success: Boolean) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/UninstallRemotePackageRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/UninstallRemotePackageRequest.kt index fc894ed92..5c59c1ac4 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/UninstallRemotePackageRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/UninstallRemotePackageRequest.kt @@ -24,7 +24,7 @@ import com.malinskiy.adam.request.shell.v1.ShellCommandRequest * There is no way to remove the remaining data. * You will have to reinstall the application with the same signature, and fully uninstall it. */ -class UninstallRemotePackageRequest( +public class UninstallRemotePackageRequest( packageName: String, keepData: Boolean = false ) : ShellCommandRequest( diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/AddSessionRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/AddSessionRequest.kt index 4270abc97..bc3860578 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/AddSessionRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/AddSessionRequest.kt @@ -23,7 +23,7 @@ import com.malinskiy.adam.request.Feature import com.malinskiy.adam.request.abb.AbbExecRequest import com.malinskiy.adam.transport.Socket -class AddSessionRequest( +public class AddSessionRequest( private val childSessions: List, private val parentSession: String, private val supportedFeatures: List diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateIndividualPackageSessionRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateIndividualPackageSessionRequest.kt index 26cf914ce..e1bf611eb 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateIndividualPackageSessionRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateIndividualPackageSessionRequest.kt @@ -24,7 +24,7 @@ import com.malinskiy.adam.request.Feature import com.malinskiy.adam.request.abb.AbbExecRequest import com.malinskiy.adam.transport.Socket -class CreateIndividualPackageSessionRequest( +public class CreateIndividualPackageSessionRequest( private val pkg: InstallationPackage, private val pkgList: List, private val supportedFeatures: List, diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateMultiPackageSessionRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateMultiPackageSessionRequest.kt index 7acf95d25..37262ba5f 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateMultiPackageSessionRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateMultiPackageSessionRequest.kt @@ -28,7 +28,7 @@ import com.malinskiy.adam.transport.Socket import java.io.File @Features(Feature.CMD, Feature.ABB_EXEC) -class CreateMultiPackageSessionRequest( +public class CreateMultiPackageSessionRequest( private val pkgList: List, private val supportedFeatures: List, private val reinstall: Boolean, @@ -134,7 +134,7 @@ class CreateMultiPackageSessionRequest( return CreateSessionResponse(sessionId, createSessionResponse) } - companion object { - val SUPPORTED_EXTENSIONS = setOf("apk", "apex") + public companion object { + public val SUPPORTED_EXTENSIONS: Set = setOf("apk", "apex") } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateSessionResponse.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateSessionResponse.kt index 7d91c1b64..a597455ce 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateSessionResponse.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateSessionResponse.kt @@ -16,4 +16,4 @@ package com.malinskiy.adam.request.pkg.multi -data class CreateSessionResponse(val id: String, val output: String) +public data class CreateSessionResponse(public val id: String, public val output: String) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/InstallCommitRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/InstallCommitRequest.kt index 5c3ff0714..5f8dcb2b5 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/InstallCommitRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/InstallCommitRequest.kt @@ -23,7 +23,7 @@ import com.malinskiy.adam.request.Feature import com.malinskiy.adam.request.abb.AbbExecRequest import com.malinskiy.adam.transport.Socket -class InstallCommitRequest( +public class InstallCommitRequest( private val parentSession: String, private val supportedFeatures: List, private val abandon: Boolean = false diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/InstallationPackage.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/InstallationPackage.kt index 5ae8d5907..300f4522c 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/InstallationPackage.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/InstallationPackage.kt @@ -18,13 +18,13 @@ package com.malinskiy.adam.request.pkg.multi import java.io.File -sealed class InstallationPackage +public sealed class InstallationPackage -data class SingleFileInstallationPackage(val file: File) : InstallationPackage() +public data class SingleFileInstallationPackage(public val file: File) : InstallationPackage() /** * Android 21+ */ -data class ApkSplitInstallationPackage(val fileList: List) : InstallationPackage() { - constructor(vararg files: File) : this(files.toList()) +public data class ApkSplitInstallationPackage(public val fileList: List) : InstallationPackage() { + public constructor(vararg files: File) : this(files.toList()) } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/WriteIndividualPackageRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/WriteIndividualPackageRequest.kt index b63f00420..090e40032 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/WriteIndividualPackageRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/WriteIndividualPackageRequest.kt @@ -27,7 +27,7 @@ import kotlinx.coroutines.Dispatchers import java.io.File import kotlin.coroutines.CoroutineContext -class WriteIndividualPackageRequest( +public class WriteIndividualPackageRequest( private val file: File, private val supportedFeatures: List, private val session: String, diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/prop/GetPropRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/prop/GetPropRequest.kt index 158f584b0..3f28aed44 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/prop/GetPropRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/prop/GetPropRequest.kt @@ -19,7 +19,7 @@ package com.malinskiy.adam.request.prop import com.malinskiy.adam.request.shell.v1.ShellCommandResult import com.malinskiy.adam.request.shell.v1.SyncShellCommandRequest -class GetPropRequest : SyncShellCommandRequest>("getprop") { +public class GetPropRequest : SyncShellCommandRequest>("getprop") { override fun convertResult(response: ShellCommandResult): Map { return response.output .lines() diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/prop/GetSinglePropRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/prop/GetSinglePropRequest.kt index b9bc58435..bc616f010 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/prop/GetSinglePropRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/prop/GetSinglePropRequest.kt @@ -19,6 +19,6 @@ package com.malinskiy.adam.request.prop import com.malinskiy.adam.request.shell.v1.ShellCommandResult import com.malinskiy.adam.request.shell.v1.SyncShellCommandRequest -class GetSinglePropRequest(name: String) : SyncShellCommandRequest("getprop $name") { - override fun convertResult(response: ShellCommandResult) = response.output +public class GetSinglePropRequest(name: String) : SyncShellCommandRequest("getprop $name") { + override fun convertResult(response: ShellCommandResult): String = response.output } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ListReversePortForwardsRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ListReversePortForwardsRequest.kt index e1f78cc2d..8d6376437 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ListReversePortForwardsRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ListReversePortForwardsRequest.kt @@ -26,7 +26,7 @@ import com.malinskiy.adam.transport.Socket /** * Doesn't work with SerialTarget, have to use the serial as a parameter for the execute method */ -class ListReversePortForwardsRequest : ComplexRequest>(target = NonSpecifiedTarget) { +public class ListReversePortForwardsRequest : ComplexRequest>(target = NonSpecifiedTarget) { override suspend fun readElement(socket: Socket): List { return socket.readProtocolString().lines().mapNotNull { line -> if (line.isNotEmpty()) { @@ -42,6 +42,6 @@ class ListReversePortForwardsRequest : ComplexRequest(target = NonSpecifiedTarget) { - override fun serialize() = createBaseRequest("reverse:killforward-all") +public class RemoveAllReversePortForwardsRequest : SynchronousRequest(target = NonSpecifiedTarget) { + override fun serialize(): ByteArray = createBaseRequest("reverse:killforward-all") - override suspend fun process(bytes: ByteArray, offset: Int, limit: Int) = Unit + override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = Unit - override fun transform() = Unit + override fun transform(): Unit = Unit } \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/RemoveReversePortForwardRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/RemoveReversePortForwardRequest.kt index 3d5a35496..51cd98347 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/RemoveReversePortForwardRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/RemoveReversePortForwardRequest.kt @@ -23,12 +23,12 @@ import com.malinskiy.adam.request.forwarding.RemotePortSpec /** * Doesn't work with SerialTarget, have to use the serial as a parameter for the execute method */ -class RemoveReversePortForwardRequest( +public class RemoveReversePortForwardRequest( private val local: RemotePortSpec ) : SynchronousRequest(target = NonSpecifiedTarget) { - override fun serialize() = createBaseRequest("reverse:killforward:${local.toSpec()}") + override fun serialize(): ByteArray = createBaseRequest("reverse:killforward:${local.toSpec()}") - override suspend fun process(bytes: ByteArray, offset: Int, limit: Int) = Unit + override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = Unit - override fun transform() = Unit + override fun transform(): Unit = Unit } \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardRequest.kt index f42b31dbf..34c8ad752 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardRequest.kt @@ -31,14 +31,14 @@ import com.malinskiy.adam.transport.Socket * * Doesn't work with SerialTarget, have to use the serial as a parameter for the execute method */ -class ReversePortForwardRequest( +public class ReversePortForwardRequest( private val local: RemotePortSpec, private val remote: LocalPortSpec, private val mode: PortForwardingMode = PortForwardingMode.DEFAULT ) : ComplexRequest(target = NonSpecifiedTarget) { - override fun serialize() = + override fun serialize(): ByteArray = createBaseRequest("reverse:forward${mode.value}:${local.toSpec()};${remote.toSpec()}") override suspend fun readElement(socket: Socket): Int? { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardingRule.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardingRule.kt index d1cc69f98..8b076a914 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardingRule.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardingRule.kt @@ -19,8 +19,8 @@ package com.malinskiy.adam.request.reverse import com.malinskiy.adam.request.forwarding.LocalPortSpec import com.malinskiy.adam.request.forwarding.RemotePortSpec -data class ReversePortForwardingRule( - val serial: String, - val localSpec: RemotePortSpec, - val remoteSpec: LocalPortSpec +public data class ReversePortForwardingRule( + public val serial: String, + public val localSpec: RemotePortSpec, + public val remoteSpec: LocalPortSpec ) \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/security/SetDmVerityCheckingRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/security/SetDmVerityCheckingRequest.kt index 5d6119b68..18017dae7 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/security/SetDmVerityCheckingRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/security/SetDmVerityCheckingRequest.kt @@ -25,17 +25,17 @@ import com.malinskiy.adam.request.transform.StringResponseTransformer * Returns a string response of executing the command. * One possible value is "verity cannot be disabled/enabled - USER build" when the device is not a debug build */ -class SetDmVerityCheckingRequest(private val enabled: Boolean) : SynchronousRequest() { +public class SetDmVerityCheckingRequest(private val enabled: Boolean) : SynchronousRequest() { private val transformer = StringResponseTransformer() - override suspend fun process(bytes: ByteArray, offset: Int, limit: Int) = transformer.process(bytes, offset, limit) + override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = transformer.process(bytes, offset, limit) - override fun serialize() = createBaseRequest( + override fun serialize(): ByteArray = createBaseRequest( when (enabled) { true -> "enable-verity:" false -> "disable-verity:" } ) - override fun transform() = transformer.transform() + override fun transform(): String = transformer.transform() } \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/AsyncCompatShellCommandRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/AsyncCompatShellCommandRequest.kt index 0a3f38a1a..bdda429dd 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/AsyncCompatShellCommandRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/AsyncCompatShellCommandRequest.kt @@ -32,15 +32,15 @@ import kotlinx.coroutines.channels.SendChannel import kotlinx.coroutines.channels.produce import com.malinskiy.adam.request.shell.v2.ChanneledShellCommandRequest as V2ChanneledShellCommandRequest -abstract class AsyncCompatShellCommandRequest( - val cmd: String, +public abstract class AsyncCompatShellCommandRequest( + public val cmd: String, private val supportedFeatures: List, private val target: Target = NonSpecifiedTarget, private val coroutineScope: CoroutineScope, private val socketIdleTimeout: Long? = null, ) : MultiRequest>() { - abstract suspend fun convertChunk(response: ShellCommandResultChunk): T? + public abstract suspend fun convertChunk(response: ShellCommandResultChunk): T? override suspend fun execute( androidDebugBridgeClient: AndroidDebugBridgeClient, @@ -75,5 +75,5 @@ abstract class AsyncCompatShellCommandRequest( } } - abstract suspend fun close(channel: SendChannel) + public abstract suspend fun close(channel: SendChannel) } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ChanneledShellCommandRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ChanneledShellCommandRequest.kt index b9277adb1..dce7bbffa 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ChanneledShellCommandRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ChanneledShellCommandRequest.kt @@ -24,8 +24,8 @@ import com.malinskiy.adam.transport.Socket import com.malinskiy.adam.transport.withMaxFilePacketBuffer import kotlinx.coroutines.channels.SendChannel -open class ChanneledShellCommandRequest( - val cmd: String, +public open class ChanneledShellCommandRequest( + public val cmd: String, target: Target = NonSpecifiedTarget, socketIdleTimeout: Long? = null ) : AsyncChannelRequest(target = target, socketIdleTimeout = socketIdleTimeout) { @@ -43,6 +43,6 @@ open class ChanneledShellCommandRequest( } } - override fun serialize() = createBaseRequest("shell:$cmd") - override suspend fun writeElement(element: Unit, socket: Socket) = Unit + override fun serialize(): ByteArray = createBaseRequest("shell:$cmd") + override suspend fun writeElement(element: Unit, socket: Socket): Unit = Unit } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellCommandRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellCommandRequest.kt index a85107422..6d20a5995 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellCommandRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellCommandRequest.kt @@ -16,6 +16,6 @@ package com.malinskiy.adam.request.shell.v1 -open class ShellCommandRequest(cmd: String) : SyncShellCommandRequest(cmd) { - override fun convertResult(response: ShellCommandResult) = response +public open class ShellCommandRequest(cmd: String) : SyncShellCommandRequest(cmd) { + override fun convertResult(response: ShellCommandResult): ShellCommandResult = response } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellCommandResult.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellCommandResult.kt index a08f79571..022d11d19 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellCommandResult.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellCommandResult.kt @@ -18,11 +18,11 @@ package com.malinskiy.adam.request.shell.v1 import com.malinskiy.adam.Const -data class ShellCommandResult( - val stdout: ByteArray, - val exitCode: Int +public data class ShellCommandResult( + public val stdout: ByteArray, + public val exitCode: Int ) { - val output: String by lazy { + public val output: String by lazy { String(stdout, Const.DEFAULT_TRANSPORT_ENCODING) } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellResultResponseTransformer.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellResultResponseTransformer.kt index 6280a15c7..5821b56d6 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellResultResponseTransformer.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellResultResponseTransformer.kt @@ -21,7 +21,7 @@ import com.malinskiy.adam.Const import com.malinskiy.adam.exception.RequestRejectedException import com.malinskiy.adam.request.transform.ResponseTransformer -class ShellResultResponseTransformer : ResponseTransformer { +public class ShellResultResponseTransformer : ResponseTransformer { override suspend fun process(bytes: ByteArray, offset: Int, limit: Int) { builder.write(bytes, 0, limit) } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/SyncShellCommandRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/SyncShellCommandRequest.kt index 341c5e763..381e8d200 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/SyncShellCommandRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/SyncShellCommandRequest.kt @@ -24,20 +24,20 @@ import com.malinskiy.adam.request.Target * shell v1 service doesn't support exit codes * we append an `echo $?` at the end to print the exit code as well and parse it */ -abstract class SyncShellCommandRequest(val cmd: String, target: Target = NonSpecifiedTarget) : +public abstract class SyncShellCommandRequest(public val cmd: String, target: Target = NonSpecifiedTarget) : SynchronousRequest(target) { /** * Descendants should override this method to map the response to appropriate output */ - abstract fun convertResult(response: ShellCommandResult): T + public abstract fun convertResult(response: ShellCommandResult): T private val responseTransformer = ShellResultResponseTransformer() - override suspend fun process(bytes: ByteArray, offset: Int, limit: Int) = responseTransformer.process(bytes, offset, limit) - override fun transform() = convertResult(responseTransformer.transform()) - override fun serialize() = createBaseRequest("shell:$cmd;echo ${EXIT_CODE_DELIMITER}$?") + override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = responseTransformer.process(bytes, offset, limit) + override fun transform(): T = convertResult(responseTransformer.transform()) + override fun serialize(): ByteArray = createBaseRequest("shell:$cmd;echo ${EXIT_CODE_DELIMITER}$?") - companion object { - const val EXIT_CODE_DELIMITER = 'x' + public companion object { + public const val EXIT_CODE_DELIMITER: Char = 'x' } } \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ChanneledShellCommandRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ChanneledShellCommandRequest.kt index 4b313fc2c..ef0025119 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ChanneledShellCommandRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ChanneledShellCommandRequest.kt @@ -24,7 +24,7 @@ import com.malinskiy.adam.transport.withMaxPacketBuffer import kotlinx.coroutines.channels.ReceiveChannel import kotlinx.coroutines.channels.SendChannel -open class ChanneledShellCommandRequest( +public open class ChanneledShellCommandRequest( private val cmd: String, channel: ReceiveChannel, target: Target = NonSpecifiedTarget, @@ -90,13 +90,13 @@ open class ChanneledShellCommandRequest( } } - override fun serialize() = createBaseRequest("shell,v2,raw:$cmd") + override fun serialize(): ByteArray = createBaseRequest("shell,v2,raw:$cmd") } -data class ShellCommandResultChunk( - val stdout: ByteArray? = null, - val stderr: ByteArray? = null, - val exitCode: Int? = null +public data class ShellCommandResultChunk( + public val stdout: ByteArray? = null, + public val stderr: ByteArray? = null, + public val exitCode: Int? = null ) { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -125,9 +125,9 @@ data class ShellCommandResultChunk( } } -data class ShellCommandInputChunk( - val stdin: ByteArray? = null, - val close: Boolean = false +public data class ShellCommandInputChunk( + public val stdin: ByteArray? = null, + public val close: Boolean = false ) { override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/MessageType.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/MessageType.kt index bfbfd45c1..8894d4a77 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/MessageType.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/MessageType.kt @@ -16,7 +16,7 @@ package com.malinskiy.adam.request.shell.v2 -enum class MessageType { +public enum class MessageType { STDIN, STDOUT, STDERR, @@ -37,7 +37,7 @@ enum class MessageType { */ INVALID; - fun toValue() = when (this) { + public fun toValue(): Int = when (this) { STDIN -> 0 STDOUT -> 1 STDERR -> 2 @@ -47,8 +47,8 @@ enum class MessageType { INVALID -> 255 } - companion object { - fun of(value: Int) = when (value) { + public companion object { + public fun of(value: Int): MessageType = when (value) { 0 -> STDIN 1 -> STDOUT 2 -> STDERR diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandRequest.kt index 25b0d039c..0a15997a3 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandRequest.kt @@ -16,7 +16,7 @@ package com.malinskiy.adam.request.shell.v2 -open class ShellCommandRequest(cmd: String, socketIdleTimeout: Long? = null) : +public open class ShellCommandRequest(cmd: String, socketIdleTimeout: Long? = null) : SyncShellCommandRequest(cmd, socketIdleTimeout = socketIdleTimeout) { - override fun convertResult(response: ShellCommandResult) = response + override fun convertResult(response: ShellCommandResult): ShellCommandResult = response } \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandResult.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandResult.kt index f4daa0797..8ea2c3877 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandResult.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandResult.kt @@ -18,16 +18,16 @@ package com.malinskiy.adam.request.shell.v2 import com.malinskiy.adam.Const -data class ShellCommandResult( - val stdout: ByteArray, - val stderr: ByteArray, - val exitCode: Int +public data class ShellCommandResult( + public val stdout: ByteArray, + public val stderr: ByteArray, + public val exitCode: Int ) { - val output: String by lazy { + public val output: String by lazy { String(stdout, Const.DEFAULT_TRANSPORT_ENCODING) } - val errorOutput: String by lazy { + public val errorOutput: String by lazy { String(stderr, Const.DEFAULT_TRANSPORT_ENCODING) } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/SyncShellCommandRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/SyncShellCommandRequest.kt index 505ccb774..c7c67d2d9 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/SyncShellCommandRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/SyncShellCommandRequest.kt @@ -27,7 +27,7 @@ import com.malinskiy.adam.transport.withMaxPacketBuffer /** * shell v2 service required for this request */ -abstract class SyncShellCommandRequest(val cmd: String, target: Target = NonSpecifiedTarget, socketIdleTimeout: Long? = null) : +public abstract class SyncShellCommandRequest(public val cmd: String, target: Target = NonSpecifiedTarget, socketIdleTimeout: Long? = null) : ComplexRequest(target, socketIdleTimeout) { private val stdoutBuilder = ByteStreams.newDataOutput() @@ -37,9 +37,9 @@ abstract class SyncShellCommandRequest(val cmd: String, target: Target /** * Descendants should override this method to map the response to appropriate output */ - abstract fun convertResult(response: ShellCommandResult): T + public abstract fun convertResult(response: ShellCommandResult): T - override fun serialize() = createBaseRequest("shell,v2,raw:$cmd") + override fun serialize(): ByteArray = createBaseRequest("shell,v2,raw:$cmd") override suspend fun readElement(socket: Socket): T { withMaxPacketBuffer { val data = array() diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/PullRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/PullRequest.kt index d1bf3554d..dfa6caa9f 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/PullRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/PullRequest.kt @@ -47,7 +47,7 @@ import kotlin.coroutines.CoroutineContext * @param source can be a file or a directory */ @Features(Feature.SENDRECV_V2, Feature.STAT_V2, Feature.LS_V2) -class PullRequest( +public class PullRequest( private val source: String, private val destination: File, private val supportedFeatures: List, diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/PushRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/PushRequest.kt index d2f3e8daa..61de396f4 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/PushRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/PushRequest.kt @@ -44,7 +44,7 @@ import kotlin.coroutines.CoroutineContext * @param source can be a file or a directory */ @Features(Feature.SENDRECV_V2, Feature.STAT_V2, Feature.LS_V2) -class PushRequest( +public class PushRequest( private val source: File, private val destination: String, private val supportedFeatures: List, diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/base/BasePullFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/base/BasePullFileRequest.kt index 7563be2e6..dbee6bcfe 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/base/BasePullFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/base/BasePullFileRequest.kt @@ -37,7 +37,7 @@ import kotlin.coroutines.CoroutineContext /** * @param coroutineContext if you don't specify your context then you'll have no control over the `wait for file to finish writing`: closing the channel doesn't close the underlying resources */ -abstract class BasePullFileRequest( +public abstract class BasePullFileRequest( private val remotePath: String, local: File, private val size: Long? = null, @@ -45,8 +45,8 @@ abstract class BasePullFileRequest( ) : AsyncChannelRequest() { private val fileWriter = AsyncFileWriter(local, coroutineContext) - var totalBytes = -1L - var currentPosition = 0L + public var totalBytes: Long = -1L + public var currentPosition: Long = 0L override suspend fun handshake(socket: Socket) { super.handshake(socket) @@ -121,7 +121,7 @@ abstract class BasePullFileRequest( } } - override fun serialize() = createBaseRequest("sync:") + override fun serialize(): ByteArray = createBaseRequest("sync:") override fun validate(): ValidationResponse { return if (remotePath.length > Const.MAX_REMOTE_PATH_LENGTH) { @@ -131,6 +131,6 @@ abstract class BasePullFileRequest( } } - override suspend fun writeElement(element: Unit, socket: Socket) = Unit + override suspend fun writeElement(element: Unit, socket: Socket): Unit = Unit } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/base/BasePushFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/base/BasePushFileRequest.kt index 5bd4716d2..60698cc90 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/base/BasePushFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/base/BasePushFileRequest.kt @@ -32,21 +32,21 @@ import kotlinx.coroutines.channels.SendChannel import java.io.File import kotlin.coroutines.CoroutineContext -abstract class BasePushFileRequest( +public abstract class BasePushFileRequest( private val local: File, protected val remotePath: String, protected val mode: String = "0777", coroutineContext: CoroutineContext = Dispatchers.IO ) : AsyncChannelRequest() { - protected val fileReader = AsyncFileReader( + protected val fileReader: AsyncFileReader = AsyncFileReader( file = local, start = 0, offset = 8, length = Const.MAX_FILE_PACKET_LENGTH - 8, coroutineContext = coroutineContext ) - protected var totalBytes = local.length() - protected var currentPosition = 0L + protected var totalBytes: Long = local.length() + protected var currentPosition: Long = 0L protected val modeValue: Int get() = mode.toInt(8) and "0777".toInt(8) @@ -96,13 +96,13 @@ abstract class BasePushFileRequest( } } - override fun serialize() = createBaseRequest("sync:") + override fun serialize(): ByteArray = createBaseRequest("sync:") override suspend fun close(channel: SendChannel) { fileReader.close() } - override suspend fun writeElement(element: Unit, socket: Socket) = Unit + override suspend fun writeElement(element: Unit, socket: Socket): Unit = Unit override fun validate(): ValidationResponse { val response = super.validate() diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatListFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatListFileRequest.kt index 46ee11a44..725c89b8b 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatListFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatListFileRequest.kt @@ -23,7 +23,7 @@ import com.malinskiy.adam.request.sync.model.FileEntry import com.malinskiy.adam.request.sync.v1.ListFileRequest import com.malinskiy.adam.request.sync.v2.ListFileRequest as ListV2FileRequest -class CompatListFileRequest( +public class CompatListFileRequest( private val path: String, private val supportedFeatures: List ) : MultiRequest>() { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatPullFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatPullFileRequest.kt index a3e6b2d27..45a7b6b07 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatPullFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatPullFileRequest.kt @@ -30,7 +30,7 @@ import com.malinskiy.adam.request.sync.v2.PullFileRequest as PullV2FileRequest /** * @param coroutineContext if you don't specify your context then you'll have no control over the `wait for file to finish writing`: closing the channel doesn't close the underlying resources */ -class CompatPullFileRequest( +public class CompatPullFileRequest( private val source: String, private val realDestination: File, private val supportedFeatures: List, diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatPushFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatPushFileRequest.kt index 78e4bca05..a555e39cb 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatPushFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatPushFileRequest.kt @@ -27,7 +27,7 @@ import java.io.File import kotlin.coroutines.CoroutineContext import com.malinskiy.adam.request.sync.v2.PushFileRequest as PushV2FileRequest -class CompatPushFileRequest( +public class CompatPushFileRequest( private val source: File, private val destination: String, private val supportedFeatures: List, diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatStatFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatStatFileRequest.kt index 37c3f576e..832235386 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatStatFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatStatFileRequest.kt @@ -23,7 +23,7 @@ import com.malinskiy.adam.request.sync.model.FileEntry import com.malinskiy.adam.request.sync.v1.StatFileRequest import com.malinskiy.adam.request.sync.v2.StatFileRequest as StatV2FileRequest -class CompatStatFileRequest( +public class CompatStatFileRequest( private val source: String, private val supportedFeatures: List ) : MultiRequest() { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/model/FileEntry.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/model/FileEntry.kt index 2c3a5989b..2579635c5 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/model/FileEntry.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/model/FileEntry.kt @@ -19,47 +19,47 @@ package com.malinskiy.adam.request.sync.model import com.malinskiy.adam.Const import java.time.Instant -sealed class FileEntry { - abstract val mode: UInt - abstract val name: String? - abstract val mtime: Instant +public sealed class FileEntry { + public abstract val mode: UInt + public abstract val name: String? + public abstract val mtime: Instant - fun isDirectory() = (mode and Const.FileType.S_IFDIR) == Const.FileType.S_IFDIR - fun isRegularFile() = (mode and Const.FileType.S_IFREG) == Const.FileType.S_IFREG - fun isBlockDevice() = (mode and Const.FileType.S_IFBLK) == Const.FileType.S_IFBLK - fun isCharDevice() = (mode and Const.FileType.S_IFCHR) == Const.FileType.S_IFCHR - fun isLink() = (mode and Const.FileType.S_IFLNK) == Const.FileType.S_IFLNK + public fun isDirectory(): Boolean = (mode and Const.FileType.S_IFDIR) == Const.FileType.S_IFDIR + public fun isRegularFile(): Boolean = (mode and Const.FileType.S_IFREG) == Const.FileType.S_IFREG + public fun isBlockDevice(): Boolean = (mode and Const.FileType.S_IFBLK) == Const.FileType.S_IFBLK + public fun isCharDevice(): Boolean = (mode and Const.FileType.S_IFCHR) == Const.FileType.S_IFCHR + public fun isLink(): Boolean = (mode and Const.FileType.S_IFLNK) == Const.FileType.S_IFLNK - fun size() = when (this) { + public fun size(): ULong = when (this) { is FileEntryV1 -> size.toLong().toULong() is FileEntryV2 -> size } - abstract fun exists(): Boolean + public abstract fun exists(): Boolean } -data class FileEntryV1( +public data class FileEntryV1( override val name: String? = null, override val mode: UInt, - val size: UInt, + public val size: UInt, override val mtime: Instant ) : FileEntry() { - override fun exists() = !(size == 0.toUInt() && mode == 0.toUInt() && mtime.epochSecond == 0L) + override fun exists(): Boolean = !(size == 0.toUInt() && mode == 0.toUInt() && mtime.epochSecond == 0L) } -data class FileEntryV2( - val error: UInt, - val dev: ULong, - val ino: ULong, +public data class FileEntryV2( + public val error: UInt, + public val dev: ULong, + public val ino: ULong, override val mode: UInt, - val nlink: UInt, - val uid: UInt, - val gid: UInt, - val size: ULong, - val atime: Instant, + public val nlink: UInt, + public val uid: UInt, + public val gid: UInt, + public val size: ULong, + public val atime: Instant, override val mtime: Instant, - val ctime: Instant, + public val ctime: Instant, override val name: String? = null ) : FileEntry() { - override fun exists() = !(size == 0.toULong() && mode == 0.toUInt() && mtime.epochSecond == 0L) + override fun exists(): Boolean = !(size == 0.toULong() && mode == 0.toUInt() && mtime.epochSecond == 0L) } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/ListFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/ListFileRequest.kt index d097718e4..91ef34dd2 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/ListFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/ListFileRequest.kt @@ -26,7 +26,7 @@ import com.malinskiy.adam.transport.Socket import com.malinskiy.adam.transport.withDefaultBuffer import java.time.Instant -class ListFileRequest( +public class ListFileRequest( private val remotePath: String ) : ComplexRequest>() { @@ -74,5 +74,5 @@ class ListFileRequest( } } - override fun serialize() = createBaseRequest("sync:") + override fun serialize(): ByteArray = createBaseRequest("sync:") } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/PullFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/PullFileRequest.kt index f8691f342..8e9eb5f88 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/PullFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/PullFileRequest.kt @@ -27,7 +27,7 @@ import kotlin.coroutines.CoroutineContext /** * @param coroutineContext if you don't specify your context then you'll have no control over the `wait for file to finish writing`: closing the channel doesn't close the underlying resources */ -class PullFileRequest( +public class PullFileRequest( private val remotePath: String, local: File, size: Long? = null, diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/PushFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/PushFileRequest.kt index 710418077..fbb1ffa50 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/PushFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/PushFileRequest.kt @@ -26,7 +26,7 @@ import kotlinx.coroutines.Dispatchers import java.io.File import kotlin.coroutines.CoroutineContext -class PushFileRequest( +public class PushFileRequest( local: File, remotePath: String, mode: String = "0777", diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/StatFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/StatFileRequest.kt index 009185669..b13e05a01 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/StatFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/StatFileRequest.kt @@ -30,7 +30,7 @@ import com.malinskiy.adam.transport.Socket import com.malinskiy.adam.transport.withDefaultBuffer import java.time.Instant -class StatFileRequest( +public class StatFileRequest( private val remotePath: String ) : ComplexRequest() { override suspend fun readElement(socket: Socket): FileEntryV1 { @@ -60,6 +60,6 @@ class StatFileRequest( } } - override fun serialize() = createBaseRequest("sync:") + override fun serialize(): ByteArray = createBaseRequest("sync:") } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/CompressionType.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/CompressionType.kt index 57d70c56e..4e3ccb904 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/CompressionType.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/CompressionType.kt @@ -16,13 +16,13 @@ package com.malinskiy.adam.request.sync.v2 -enum class CompressionType { +public enum class CompressionType { NONE, BROTLI, LZ4, Zstd; - fun toFlag() = when (this) { + public fun toFlag(): Int = when (this) { NONE -> 0 BROTLI -> 1 LZ4 -> 2 diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/ListFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/ListFileRequest.kt index b8bf77ad1..f4ffbcea4 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/ListFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/ListFileRequest.kt @@ -32,7 +32,7 @@ import com.malinskiy.adam.transport.withDefaultBuffer import java.time.Instant @Features(Feature.LS_V2) -class ListFileRequest( +public class ListFileRequest( private val remotePath: String, private val supportedFeatures: List ) : ComplexRequest>() { @@ -102,5 +102,5 @@ class ListFileRequest( } } - override fun serialize() = createBaseRequest("sync:") + override fun serialize(): ByteArray = createBaseRequest("sync:") } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/PullFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/PullFileRequest.kt index 019da427c..03221fd5f 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/PullFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/PullFileRequest.kt @@ -31,7 +31,7 @@ import kotlin.coroutines.CoroutineContext * @param coroutineContext if you don't specify your context then you'll have no control over the `wait for file to finish writing`: closing the channel doesn't close the underlying resources */ @Features(Feature.SENDRECV_V2) -class PullFileRequest( +public class PullFileRequest( private val remotePath: String, local: File, private val supportedFeatures: List, diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/PushFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/PushFileRequest.kt index 973b95091..c51816a47 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/PushFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/PushFileRequest.kt @@ -31,12 +31,12 @@ import kotlin.coroutines.CoroutineContext * @param dryRun if true, requires SENDRECV_V2_DRY_RUN_SEND */ @Features(Feature.SENDRECV_V2, Feature.SENDRECV_V2_DRY_RUN_SEND) -class PushFileRequest( +public class PushFileRequest( local: File, remotePath: String, - val supportedFeatures: List, + public val supportedFeatures: List, mode: String = "0777", - val dryRun: Boolean = false, + public val dryRun: Boolean = false, coroutineContext: CoroutineContext = Dispatchers.IO ) : BasePushFileRequest(local, remotePath, mode, coroutineContext) { /** @@ -67,7 +67,7 @@ class PushFileRequest( } } - companion object { - val DRY_RUN_FLAG = 0x8000_0000 + public companion object { + public val DRY_RUN_FLAG: Long = 0x8000_0000 } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/StatFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/StatFileRequest.kt index d968eac88..8091a16ae 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/StatFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/StatFileRequest.kt @@ -32,7 +32,7 @@ import com.malinskiy.adam.transport.withDefaultBuffer import java.time.Instant @Features(Feature.STAT_V2) -class StatFileRequest( +public class StatFileRequest( private val remotePath: String, private val supportedFeatures: List ) : ComplexRequest() { @@ -74,6 +74,6 @@ class StatFileRequest( } } - override fun serialize() = createBaseRequest("sync:") + override fun serialize(): ByteArray = createBaseRequest("sync:") } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/InstrumentOptions.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/InstrumentOptions.kt index d2714a98c..a371e53d1 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/InstrumentOptions.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/InstrumentOptions.kt @@ -53,20 +53,20 @@ import java.util.* * @param coverageFile Overrides the default location of the EMMA coverage file on the device. * Specify this value as a path and filename in UNIX format. The default filename is described in the entry for the [emma] key. */ -data class InstrumentOptions( - val pkg: List = emptyList(), - val clazz: List = emptyList(), - val functional: Boolean? = null, - val unit: Boolean? = null, - val filterSize: InstrumentationSizeOption? = null, - val performance: Boolean? = null, - val debug: Boolean? = null, - val log: Boolean? = null, - val emma: Boolean? = null, - val coverageFile: String? = null, - val overrides: Map = mapOf() +public data class InstrumentOptions( + public val pkg: List = emptyList(), + public val clazz: List = emptyList(), + public val functional: Boolean? = null, + public val unit: Boolean? = null, + public val filterSize: InstrumentationSizeOption? = null, + public val performance: Boolean? = null, + public val debug: Boolean? = null, + public val log: Boolean? = null, + public val emma: Boolean? = null, + public val coverageFile: String? = null, + public val overrides: Map = mapOf() ) { - override fun toString() = StringBuilder().apply { + override fun toString(): String = StringBuilder().apply { if (pkg.isNotEmpty()) append(" -e package " + pkg.joinToString(separator = ",")) if (clazz.isNotEmpty()) append(" -e class " + clazz.joinToString(separator = ",")) if (functional != null) append(" -e func $functional") diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/InstrumentationSizeOption.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/InstrumentationSizeOption.kt index c63893037..66d2acee2 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/InstrumentationSizeOption.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/InstrumentationSizeOption.kt @@ -16,7 +16,7 @@ package com.malinskiy.adam.request.testrunner -enum class InstrumentationSizeOption { +public enum class InstrumentationSizeOption { SMALL, MEDIUM, LARGE diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestEvent.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestEvent.kt index d081ce7b9..5776aa77d 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestEvent.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestEvent.kt @@ -16,16 +16,16 @@ package com.malinskiy.adam.request.testrunner -sealed class TestEvent +public sealed class TestEvent -data class TestRunStartedEvent(val testCount: Int) : TestEvent() -data class TestStarted(val id: TestIdentifier) : TestEvent() -data class TestFailed(val id: TestIdentifier, val stackTrace: String) : TestEvent() -data class TestAssumptionFailed(val id: TestIdentifier, val stackTrace: String) : TestEvent() -data class TestIgnored(val id: TestIdentifier) : TestEvent() -data class TestEnded(val id: TestIdentifier, val metrics: Map) : TestEvent() -data class TestRunFailed(val error: String) : TestEvent() -data class TestRunFailing(val error: String, val stackTrace: String) : TestEvent() -data class TestRunStopped(val elapsedTimeMillis: Long) : TestEvent() -data class TestRunEnded(val elapsedTimeMillis: Long, val metrics: Map) : TestEvent() -data class TestLogcat(val id: TestIdentifier, val log: String) +public data class TestRunStartedEvent(public val testCount: Int) : TestEvent() +public data class TestStarted(public val id: TestIdentifier) : TestEvent() +public data class TestFailed(public val id: TestIdentifier, public val stackTrace: String) : TestEvent() +public data class TestAssumptionFailed(public val id: TestIdentifier, public val stackTrace: String) : TestEvent() +public data class TestIgnored(public val id: TestIdentifier) : TestEvent() +public data class TestEnded(public val id: TestIdentifier, public val metrics: Map) : TestEvent() +public data class TestRunFailed(public val error: String) : TestEvent() +public data class TestRunFailing(public val error: String, public val stackTrace: String) : TestEvent() +public data class TestRunStopped(public val elapsedTimeMillis: Long) : TestEvent() +public data class TestRunEnded(public val elapsedTimeMillis: Long, public val metrics: Map) : TestEvent() +public data class TestLogcat(public val id: TestIdentifier, public val log: String) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestIdentifier.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestIdentifier.kt index 3da627ca6..37768beaf 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestIdentifier.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestIdentifier.kt @@ -16,7 +16,7 @@ package com.malinskiy.adam.request.testrunner -data class TestIdentifier( - val className: String, - val testName: String +public data class TestIdentifier( + public val className: String, + public val testName: String ) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestRunnerRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestRunnerRequest.kt index d3ef45943..c2cbc03b2 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestRunnerRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestRunnerRequest.kt @@ -44,7 +44,7 @@ import java.io.File * * @see https://android.googlesource.com/platform/frameworks/base/+/master/cmds/am/src/com/android/commands/am/Am.java#155 */ -class TestRunnerRequest( +public class TestRunnerRequest( private val testPackage: String, private val instrumentOptions: InstrumentOptions, private val supportedFeatures: List, diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/SessionResultCode.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/SessionResultCode.kt index 79f3130fd..1037409c5 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/SessionResultCode.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/SessionResultCode.kt @@ -16,7 +16,7 @@ package com.malinskiy.adam.request.testrunner.model -enum class SessionResultCode(val value: Int) { +public enum class SessionResultCode(public val value: Int) { FINISHED(-1), ERROR(0) } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/State.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/State.kt index 846a6d582..15015c223 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/State.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/State.kt @@ -16,9 +16,9 @@ package com.malinskiy.adam.request.testrunner.model -sealed class State(val terminal: Boolean) +public sealed class State(public val terminal: Boolean) -object NotStarted : State(false) -object Running : State(false) -object Finished : State(true) -object Cancelled : State(true) +public object NotStarted : State(false) +public object Running : State(false) +public object Finished : State(true) +public object Cancelled : State(true) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/Status.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/Status.kt index 8676356ef..9910de4d1 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/Status.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/Status.kt @@ -16,7 +16,7 @@ package com.malinskiy.adam.request.testrunner.model -enum class Status(val value: Int) { +public enum class Status(public val value: Int) { SUCCESS(0), START(1), IN_PROGRESS(2), @@ -30,10 +30,10 @@ enum class Status(val value: Int) { ASSUMPTION_FAILURE(-4), UNKNOWN(6666); - fun isTerminal() = value < 0 + public fun isTerminal(): Boolean = value < 0 - companion object { - fun valueOf(value: Int?): Status { + public companion object { + public fun valueOf(value: Int?): Status { return when (value) { 0 -> SUCCESS 1 -> START diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/StatusKey.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/StatusKey.kt index 5d0a2e323..ed254e894 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/StatusKey.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/StatusKey.kt @@ -16,7 +16,7 @@ package com.malinskiy.adam.request.testrunner.model -enum class StatusKey(val value: String) { +public enum class StatusKey(public val value: String) { TEST("test"), CLASS("class"), STACK("stack"), @@ -28,8 +28,8 @@ enum class StatusKey(val value: String) { ID("id"), UNKNOWN(""); - companion object { - fun of(value: String?) = when (value) { + public companion object { + public fun of(value: String?): StatusKey = when (value) { "test" -> TEST "class" -> CLASS "stack" -> STACK diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/TestStatusAggregator.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/TestStatusAggregator.kt index 673b7aaa5..bbab467e0 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/TestStatusAggregator.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/TestStatusAggregator.kt @@ -18,8 +18,8 @@ package com.malinskiy.adam.request.testrunner.model import com.malinskiy.adam.Const -data class TestStatusAggregator( - var statusCode: Status, - val logcatBuilder: StringBuilder = StringBuilder(Const.MAX_PROTOBUF_LOGCAT_LENGTH), - val metrics: MutableMap = mutableMapOf() +public data class TestStatusAggregator( + public var statusCode: Status, + public val logcatBuilder: StringBuilder = StringBuilder(Const.MAX_PROTOBUF_LOGCAT_LENGTH), + public val metrics: MutableMap = mutableMapOf() ) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/TokenType.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/TokenType.kt index 01b615c9f..7e63ec9c7 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/TokenType.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/TokenType.kt @@ -16,7 +16,7 @@ package com.malinskiy.adam.request.testrunner.model -enum class TokenType { +public enum class TokenType { INSTRUMENTATION_STATUS, INSTRUMENTATION_STATUS_CODE, INSTRUMENTATION_RESULT, diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformer.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformer.kt index fd43a2e3b..b964efa1a 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformer.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformer.kt @@ -31,8 +31,8 @@ import com.malinskiy.adam.request.testrunner.TestStarted import com.malinskiy.adam.request.testrunner.model.Status import com.malinskiy.adam.request.testrunner.model.TokenType -class InstrumentationResponseTransformer : ProgressiveResponseTransformer?> { - var buffer = StringBuffer() +public class InstrumentationResponseTransformer : ProgressiveResponseTransformer?> { + public var buffer: StringBuffer = StringBuffer() private var startReported = false private var finishReported = false @@ -257,8 +257,8 @@ class InstrumentationResponseTransformer : ProgressiveResponseTransformer = setOf("test", "class", "stack", "numtests", "Error", "shortMsg", "stream", "current", "id") } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/ProtoInstrumentationResponseTransformer.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/ProtoInstrumentationResponseTransformer.kt index d2a8e4cfc..4f6372ac6 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/ProtoInstrumentationResponseTransformer.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/ProtoInstrumentationResponseTransformer.kt @@ -42,7 +42,7 @@ import java.nio.channels.FileChannel * * see frameworks/base/cmds/am/src/com/android/commands/am/Instrument.java#readLogcat */ -class ProtoInstrumentationResponseTransformer(maxProtobufPacketLength: Long = Const.MAX_PROTOBUF_PACKET_LENGTH) : +public class ProtoInstrumentationResponseTransformer(maxProtobufPacketLength: Long = Const.MAX_PROTOBUF_PACKET_LENGTH) : ProgressiveResponseTransformer?> { private val backingFile = RandomAccessFile(File.createTempFile("tmp-proto", null, null), "rw") private val channel = backingFile.channel diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/transform/DumpResponseTransformer.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/transform/DumpResponseTransformer.kt index a79e31fee..724e41efa 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/transform/DumpResponseTransformer.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/transform/DumpResponseTransformer.kt @@ -22,7 +22,7 @@ import java.io.File import java.io.FileOutputStream import kotlin.coroutines.CoroutineContext -class DumpResponseTransformer( +public class DumpResponseTransformer( private val file: File, private val delegate: ProgressiveResponseTransformer, private val dumpContext: CoroutineContext = Dispatchers.IO, diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/transform/ProgressiveResponseTransformer.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/transform/ProgressiveResponseTransformer.kt index 9af68d785..6cbad986d 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/transform/ProgressiveResponseTransformer.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/transform/ProgressiveResponseTransformer.kt @@ -16,7 +16,7 @@ package com.malinskiy.adam.request.transform -interface ProgressiveResponseTransformer { - suspend fun process(bytes: ByteArray, offset: Int, limit: Int): T - fun transform(): T +public interface ProgressiveResponseTransformer { + public suspend fun process(bytes: ByteArray, offset: Int, limit: Int): T + public fun transform(): T } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/transform/ResponseTransformer.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/transform/ResponseTransformer.kt index caa28f8c1..b26825407 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/transform/ResponseTransformer.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/transform/ResponseTransformer.kt @@ -16,7 +16,7 @@ package com.malinskiy.adam.request.transform -interface ResponseTransformer { - suspend fun process(bytes: ByteArray, offset: Int, limit: Int) - fun transform(): T +public interface ResponseTransformer { + public suspend fun process(bytes: ByteArray, offset: Int, limit: Int) + public fun transform(): T } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/transform/StringResponseTransformer.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/transform/StringResponseTransformer.kt index f86f992c7..b3a5a522e 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/transform/StringResponseTransformer.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/transform/StringResponseTransformer.kt @@ -18,7 +18,7 @@ package com.malinskiy.adam.request.transform import com.malinskiy.adam.Const -class StringResponseTransformer : ResponseTransformer { +public class StringResponseTransformer : ResponseTransformer { override suspend fun process(bytes: ByteArray, offset: Int, limit: Int) { val part = String(bytes, 0, limit, Const.DEFAULT_TRANSPORT_ENCODING) builder.append(part) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/BufferFactory.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/BufferFactory.kt index ddea67bc0..0bedaa9e7 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/BufferFactory.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/BufferFactory.kt @@ -28,11 +28,11 @@ import java.nio.ByteOrder internal const val DEFAULT_BUFFER_SIZE = 4088 -val AdamDefaultPool: ByteBufferPool = ByteBufferPool(poolSize = Const.DEFAULT_BUFFER_SIZE, bufferSize = DEFAULT_BUFFER_SIZE) -val AdamMaxPacketPool: ByteBufferPool = ByteBufferPool(poolSize = Const.DEFAULT_BUFFER_SIZE, bufferSize = Const.MAX_PACKET_LENGTH) -val AdamMaxFilePacketPool: ByteBufferPool = ByteBufferPool(poolSize = Const.DEFAULT_BUFFER_SIZE, bufferSize = Const.MAX_FILE_PACKET_LENGTH) +public val AdamDefaultPool: ByteBufferPool = ByteBufferPool(poolSize = Const.DEFAULT_BUFFER_SIZE, bufferSize = DEFAULT_BUFFER_SIZE) +public val AdamMaxPacketPool: ByteBufferPool = ByteBufferPool(poolSize = Const.DEFAULT_BUFFER_SIZE, bufferSize = Const.MAX_PACKET_LENGTH) +public val AdamMaxFilePacketPool: ByteBufferPool = ByteBufferPool(poolSize = Const.DEFAULT_BUFFER_SIZE, bufferSize = Const.MAX_FILE_PACKET_LENGTH) -class ByteBufferPool(private val poolSize: Int, private val bufferSize: Int) { +public class ByteBufferPool(private val poolSize: Int, private val bufferSize: Int) { private val delegate: GenericObjectPool by lazy { val config = GenericObjectPoolConfig().apply { maxTotal = poolSize @@ -41,12 +41,12 @@ class ByteBufferPool(private val poolSize: Int, private val bufferSize: Int) { GenericObjectPool(ByteBufferObjectFactory(bufferSize), config) } - fun borrow(): ByteBuffer = delegate.borrowObject() + public fun borrow(): ByteBuffer = delegate.borrowObject() - fun recycle(buffer: ByteBuffer) = delegate.returnObject(buffer) + public fun recycle(buffer: ByteBuffer): Unit = delegate.returnObject(buffer) } -class ByteBufferObjectFactory(private val bufferSize: Int) : PooledObjectFactory { +public class ByteBufferObjectFactory(private val bufferSize: Int) : PooledObjectFactory { override fun activateObject(p: PooledObject?) { p?.`object`?.apply { compatClear() @@ -79,7 +79,7 @@ class ByteBufferObjectFactory(private val bufferSize: Int) : PooledObjectFactory } } -inline fun withDefaultBuffer(block: ByteBuffer.() -> R): R { +public inline fun withDefaultBuffer(block: ByteBuffer.() -> R): R { val instance = AdamDefaultPool.borrow() return try { block(instance) @@ -88,7 +88,7 @@ inline fun withDefaultBuffer(block: ByteBuffer.() -> R): R { } } -inline fun withMaxPacketBuffer(block: ByteBuffer.() -> R): R { +public inline fun withMaxPacketBuffer(block: ByteBuffer.() -> R): R { val instance = AdamMaxPacketPool.borrow() return try { block(instance) @@ -97,7 +97,7 @@ inline fun withMaxPacketBuffer(block: ByteBuffer.() -> R): R { } } -inline fun withMaxFilePacketBuffer(block: ByteBuffer.() -> R): R { +public inline fun withMaxFilePacketBuffer(block: ByteBuffer.() -> R): R { val instance = AdamMaxFilePacketPool.borrow() return try { block(instance) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/Socket.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/Socket.kt index d89e78316..ff0178983 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/Socket.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/Socket.kt @@ -18,22 +18,22 @@ package com.malinskiy.adam.transport import java.nio.ByteBuffer -interface Socket : SuspendCloseable { - val isClosedForWrite: Boolean - val isClosedForRead: Boolean +public interface Socket : SuspendCloseable { + public val isClosedForWrite: Boolean + public val isClosedForRead: Boolean - suspend fun writeFully(byteBuffer: ByteBuffer) - suspend fun writeFully(byteArray: ByteArray, offset: Int, limit: Int) + public suspend fun writeFully(byteBuffer: ByteBuffer) + public suspend fun writeFully(byteArray: ByteArray, offset: Int, limit: Int) - suspend fun readAvailable(buffer: ByteArray, offset: Int, limit: Int): Int - suspend fun readFully(buffer: ByteBuffer): Int - suspend fun readFully(buffer: ByteArray, offset: Int, limit: Int) + public suspend fun readAvailable(buffer: ByteArray, offset: Int, limit: Int): Int + public suspend fun readFully(buffer: ByteBuffer): Int + public suspend fun readFully(buffer: ByteArray, offset: Int, limit: Int) - suspend fun readByte(): Byte - suspend fun writeByte(value: Int) + public suspend fun readByte(): Byte + public suspend fun writeByte(value: Int) - suspend fun readIntLittleEndian(): Int - suspend fun writeIntLittleEndian(value: Int) + public suspend fun readIntLittleEndian(): Int + public suspend fun writeIntLittleEndian(value: Int) - suspend fun writeFully(byteArray: ByteArray) = writeFully(byteArray, 0, byteArray.size) + public suspend fun writeFully(byteArray: ByteArray): Unit = writeFully(byteArray, 0, byteArray.size) } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/SocketFactory.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/SocketFactory.kt index 379077a26..efe176d4d 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/SocketFactory.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/SocketFactory.kt @@ -19,7 +19,7 @@ package com.malinskiy.adam.transport import java.io.Closeable import java.net.InetSocketAddress -interface SocketFactory : Closeable { - suspend fun tcp(socketAddress: InetSocketAddress, connectTimeout: Long? = null, idleTimeout: Long? = null): Socket +public interface SocketFactory : Closeable { + public suspend fun tcp(socketAddress: InetSocketAddress, connectTimeout: Long? = null, idleTimeout: Long? = null): Socket override fun close() } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/SuspendCloseable.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/SuspendCloseable.kt index 9810d25ca..be22e98f5 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/SuspendCloseable.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/SuspendCloseable.kt @@ -19,11 +19,11 @@ package com.malinskiy.adam.transport import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.withContext -interface SuspendCloseable { - suspend fun close() +public interface SuspendCloseable { + public suspend fun close() } -suspend inline fun C.use(crossinline block: suspend (C) -> R): R { +public suspend inline fun C.use(crossinline block: suspend (C) -> R): R { var closed = false return try { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/TransportResponse.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/TransportResponse.kt index 98bfce946..7b4fdbccb 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/TransportResponse.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/TransportResponse.kt @@ -16,7 +16,7 @@ package com.malinskiy.adam.transport -class TransportResponse( - val okay: Boolean, - val message: String? +public class TransportResponse( + public val okay: Boolean, + public val message: String? ) \ No newline at end of file diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VariableSizeRecordParser.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VariableSizeRecordParser.kt index c9ec118a7..d9f2985e1 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VariableSizeRecordParser.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VariableSizeRecordParser.kt @@ -21,7 +21,7 @@ import io.vertx.core.buffer.Buffer import io.vertx.core.streams.ReadStream import kotlin.math.min -class VariableSizeRecordParser( +public class VariableSizeRecordParser( private val stream: ReadStream? = null ) : Handler, ReadStream { // Empty and unmodifiable @@ -60,7 +60,7 @@ class VariableSizeRecordParser( } } - fun request(size: Int) { + public fun request(size: Int) { require(size > 0) { "Size must be > 0" } requestedAtMost = size handleParsing() @@ -133,7 +133,7 @@ class VariableSizeRecordParser( endHandler?.handle(null) } - override fun exceptionHandler(handler: Handler?) = apply { exceptionHandler = handler } + override fun exceptionHandler(handler: Handler?): VariableSizeRecordParser = apply { exceptionHandler = handler } override fun handler(handler: Handler?): ReadStream { eventHandler = handler @@ -156,7 +156,7 @@ class VariableSizeRecordParser( return this } - override fun pause() = apply { demand = 0L } + override fun pause(): VariableSizeRecordParser = apply { demand = 0L } override fun fetch(amount: Long): ReadStream { require(amount > 0) { "Fetch amount must be > 0" } @@ -168,7 +168,7 @@ class VariableSizeRecordParser( return this } - override fun resume() = apply { fetch(Long.MAX_VALUE) } + override fun resume(): VariableSizeRecordParser = apply { fetch(Long.MAX_VALUE) } - override fun endHandler(handler: Handler?) = apply { endHandler = handler } + override fun endHandler(handler: Handler?): VariableSizeRecordParser = apply { endHandler = handler } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocket.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocket.kt index e492fe65d..1cb0eea2b 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocket.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocket.kt @@ -45,9 +45,9 @@ import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicReference import kotlin.coroutines.CoroutineContext -class VertxSocket(private val socketAddress: SocketAddress, private val options: NetClientOptions) : CoroutineVerticle(), Socket { - var id: String? = null - var netClient: NetClient? = null +public class VertxSocket(private val socketAddress: SocketAddress, private val options: NetClientOptions) : CoroutineVerticle(), Socket { + public var id: String? = null + public var netClient: NetClient? = null private lateinit var socket: NetSocketImpl private lateinit var recordParser: VariableSizeRecordParser private lateinit var readChannel: ReceiveChannel @@ -98,7 +98,7 @@ class VertxSocket(private val socketAddress: SocketAddress, private val options: socket.write(appendBytes).coAwait() } - suspend fun writeFully(buffer: Buffer) { + public suspend fun writeFully(buffer: Buffer) { if (isClosedForWrite) throw IllegalStateException("Socket write error: socket is not connected ${state.get()}") socket.write(buffer).coAwait() } @@ -200,7 +200,7 @@ class VertxSocket(private val socketAddress: SocketAddress, private val options: } } -fun ReadStream.toChannel(vertx: Vertx): ReceiveChannel { +public fun ReadStream.toChannel(vertx: Vertx): ReceiveChannel { return toChannel(vertx.orCreateContext) } @@ -209,7 +209,7 @@ fun ReadStream.toChannel(vertx: Vertx): ReceiveChannel { * * @param context the vertx context */ -fun ReadStream.toChannel(context: Context): ReceiveChannel { +public fun ReadStream.toChannel(context: Context): ReceiveChannel { this.pause() val ret = ChannelReadStream( stream = this, diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocketFactory.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocketFactory.kt index c821dc9e9..3d6df8e7b 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocketFactory.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocketFactory.kt @@ -25,7 +25,7 @@ import io.vertx.kotlin.coroutines.coAwait import java.net.InetSocketAddress import java.util.concurrent.atomic.AtomicBoolean -class VertxSocketFactory( +public class VertxSocketFactory( private val connectTimeout: Long = 10_000, private val idleTimeout: Long = 30_000 ) : SocketFactory { From 3bbaf3c40ee0dcc93ca5829acc161b1f074f7f1d Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sat, 14 Feb 2026 17:00:03 +0000 Subject: [PATCH 08/50] chore: enabled explicitApi in transport-ktor and server-stub modules --- server/server-stub-junit4/build.gradle.kts | 4 + .../adam/server/junit4/AdbServerRule.kt | 8 +- .../adam/server/junit4/AdbServerRuleTest.kt | 8 +- server/server-stub-junit5/build.gradle.kts | 4 + .../malinskiy/adam/server/junit5/AdbClient.kt | 2 +- .../malinskiy/adam/server/junit5/AdbServer.kt | 2 +- .../adam/server/junit5/AdbServerExtension.kt | 8 +- .../malinskiy/adam/server/junit5/AdbTest.kt | 2 +- .../server/junit5/AdbServerExtensionTest.kt | 10 +- server/server-stub/build.gradle.kts | 4 + .../server/stub/AndroidDebugBridgeServer.kt | 20 ++-- .../adam/server/stub/ConsoleReadChannel.kt | 8 +- .../adam/server/stub/ConsoleWriteChannel.kt | 8 +- .../adam/server/stub/EmulatorConsoleServer.kt | 8 +- .../adam/server/stub/ServerReadChannel.kt | 36 +++---- .../adam/server/stub/ServerWriteChannel.kt | 54 +++++----- .../malinskiy/adam/server/stub/StubSocket.kt | 12 +-- .../adam/server/stub/dsl/DeviceExpectation.kt | 8 +- .../server/stub/dsl/DoneFailSubSession.kt | 6 +- .../adam/server/stub/dsl/ExecSubSession.kt | 10 +- .../adam/server/stub/dsl/Expectation.kt | 8 +- .../server/stub/dsl/FramebufferSubSession.kt | 10 +- .../server/stub/dsl/GetAdbServerSubSession.kt | 8 +- .../stub/dsl/LegacySideloadSubSession.kt | 8 +- .../server/stub/dsl/OkayFailSubSession.kt | 6 +- .../server/stub/dsl/ReceiveFileSubSession.kt | 6 +- .../server/stub/dsl/SendFileSubSession.kt | 8 +- .../server/stub/dsl/SendFileV2SubSession.kt | 8 +- .../malinskiy/adam/server/stub/dsl/Session.kt | 100 +++++++++--------- .../adam/server/stub/dsl/ShellV1SubSession.kt | 8 +- .../adam/server/stub/dsl/ShellV2SubSession.kt | 12 +-- transport-ktor/build.gradle.kts | 4 + .../adam/transport/ktor/KtorSocket.kt | 4 +- .../adam/transport/ktor/KtorSocketFactory.kt | 2 +- 34 files changed, 217 insertions(+), 197 deletions(-) diff --git a/server/server-stub-junit4/build.gradle.kts b/server/server-stub-junit4/build.gradle.kts index 7730cc603..7ee8127c9 100644 --- a/server/server-stub-junit4/build.gradle.kts +++ b/server/server-stub-junit4/build.gradle.kts @@ -19,6 +19,10 @@ plugins { id("jacoco") } +kotlin { + explicitApi() +} + tasks.jacocoTestReport { reports { diff --git a/server/server-stub-junit4/src/main/kotlin/com/malinskiy/adam/server/junit4/AdbServerRule.kt b/server/server-stub-junit4/src/main/kotlin/com/malinskiy/adam/server/junit4/AdbServerRule.kt index d73600524..d2bd61150 100644 --- a/server/server-stub-junit4/src/main/kotlin/com/malinskiy/adam/server/junit4/AdbServerRule.kt +++ b/server/server-stub-junit4/src/main/kotlin/com/malinskiy/adam/server/junit4/AdbServerRule.kt @@ -26,9 +26,9 @@ import org.junit.rules.TestRule import org.junit.runner.Description import org.junit.runners.model.Statement -class AdbServerRule : TestRule { - lateinit var server: AndroidDebugBridgeServer - val client: AndroidDebugBridgeClient +public class AdbServerRule : TestRule { + public lateinit var server: AndroidDebugBridgeServer + public val client: AndroidDebugBridgeClient get() = server.client override fun apply(base: Statement, description: Description): Statement { @@ -50,7 +50,7 @@ class AdbServerRule : TestRule { } } - fun session(block: suspend Session.() -> Unit) { + public fun session(block: suspend Session.() -> Unit) { server.session(block) } } diff --git a/server/server-stub-junit4/src/test/kotlin/com/malinskiy/adam/server/junit4/AdbServerRuleTest.kt b/server/server-stub-junit4/src/test/kotlin/com/malinskiy/adam/server/junit4/AdbServerRuleTest.kt index 771c1fd98..33d40bec3 100644 --- a/server/server-stub-junit4/src/test/kotlin/com/malinskiy/adam/server/junit4/AdbServerRuleTest.kt +++ b/server/server-stub-junit4/src/test/kotlin/com/malinskiy/adam/server/junit4/AdbServerRuleTest.kt @@ -22,14 +22,14 @@ import kotlinx.coroutines.runBlocking import org.junit.Rule import org.junit.Test -class AdbServerRuleTest { +public class AdbServerRuleTest { @get:Rule - val server = AdbServerRule() - val client: AndroidDebugBridgeClient + public val server: AdbServerRule = AdbServerRule() + public val client: AndroidDebugBridgeClient get() = server.client @Test - fun test() { + public fun test() { server.session { expectAdbServerVersion() .accept() diff --git a/server/server-stub-junit5/build.gradle.kts b/server/server-stub-junit5/build.gradle.kts index 931ea8a0d..8d53cf5c8 100644 --- a/server/server-stub-junit5/build.gradle.kts +++ b/server/server-stub-junit5/build.gradle.kts @@ -19,6 +19,10 @@ plugins { id("jacoco") } +kotlin { + explicitApi() +} + tasks.jacocoTestReport { reports { xml.required.set(true) diff --git a/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbClient.kt b/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbClient.kt index 068db20d8..baf4bbe4b 100644 --- a/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbClient.kt +++ b/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbClient.kt @@ -18,4 +18,4 @@ package com.malinskiy.adam.server.junit5 @Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) @Retention(AnnotationRetention.RUNTIME) -annotation class AdbClient +public annotation class AdbClient diff --git a/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbServer.kt b/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbServer.kt index 6c798e109..4d5d22abb 100644 --- a/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbServer.kt +++ b/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbServer.kt @@ -18,4 +18,4 @@ package com.malinskiy.adam.server.junit5 @Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY) @Retention(AnnotationRetention.RUNTIME) -annotation class AdbServer +public annotation class AdbServer diff --git a/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbServerExtension.kt b/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbServerExtension.kt index 40900ef1a..d7ed4056c 100644 --- a/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbServerExtension.kt +++ b/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbServerExtension.kt @@ -32,12 +32,12 @@ import kotlin.reflect.full.isSubtypeOf import kotlin.reflect.full.memberProperties -class AdbServerExtension : BeforeEachCallback, AfterEachCallback { - lateinit var server: AndroidDebugBridgeServer - val client: AndroidDebugBridgeClient +public class AdbServerExtension : BeforeEachCallback, AfterEachCallback { + public lateinit var server: AndroidDebugBridgeServer + public val client: AndroidDebugBridgeClient get() = server.client - fun session(block: suspend Session.() -> Unit) { + public fun session(block: suspend Session.() -> Unit) { server.listen { input, output -> val session = Session(input, output) block(session) diff --git a/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbTest.kt b/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbTest.kt index f2a4d89c2..4771decb1 100644 --- a/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbTest.kt +++ b/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbTest.kt @@ -23,4 +23,4 @@ import java.lang.annotation.Inherited @ExtendWith(AdbServerExtension::class) @Inherited @Retention(AnnotationRetention.RUNTIME) -annotation class AdbTest +public annotation class AdbTest diff --git a/server/server-stub-junit5/src/test/kotlin/com/malinskiy/adam/server/junit5/AdbServerExtensionTest.kt b/server/server-stub-junit5/src/test/kotlin/com/malinskiy/adam/server/junit5/AdbServerExtensionTest.kt index f17dadd22..2d046a862 100644 --- a/server/server-stub-junit5/src/test/kotlin/com/malinskiy/adam/server/junit5/AdbServerExtensionTest.kt +++ b/server/server-stub-junit5/src/test/kotlin/com/malinskiy/adam/server/junit5/AdbServerExtensionTest.kt @@ -27,15 +27,15 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(AdbServerExtension::class) -class AdbServerExtensionTest { +public class AdbServerExtensionTest { @AdbClient - lateinit var client: AndroidDebugBridgeClient + public lateinit var client: AndroidDebugBridgeClient @AdbServer - lateinit var server: AndroidDebugBridgeServer + public lateinit var server: AndroidDebugBridgeServer @Test - fun testX() { + public fun testX() { server.session { expectAdbServerVersion() .accept() @@ -49,7 +49,7 @@ class AdbServerExtensionTest { } @Test - fun testMultisession() { + public fun testMultisession() { runBlocking { server.multipleSessions { serial("emulator-5554") { diff --git a/server/server-stub/build.gradle.kts b/server/server-stub/build.gradle.kts index 93288d76b..c6ad7afff 100644 --- a/server/server-stub/build.gradle.kts +++ b/server/server-stub/build.gradle.kts @@ -19,6 +19,10 @@ plugins { id("jacoco") } +kotlin { + explicitApi() +} + sourceSets { create("integrationTest") { diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/AndroidDebugBridgeServer.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/AndroidDebugBridgeServer.kt index 022a41432..ef8a5f483 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/AndroidDebugBridgeServer.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/AndroidDebugBridgeServer.kt @@ -41,26 +41,26 @@ import kotlinx.coroutines.runBlocking import kotlin.coroutines.CoroutineContext -class AndroidDebugBridgeServer : CoroutineScope { +public class AndroidDebugBridgeServer : CoroutineScope { private val executionDispatcher by lazy { newFixedThreadPoolContext(4, "AndroidDebugBridgeServer") } override val coroutineContext: CoroutineContext get() = executionDispatcher - val client: AndroidDebugBridgeClient by lazy { + public val client: AndroidDebugBridgeClient by lazy { AndroidDebugBridgeClientFactory().apply { port = this@AndroidDebugBridgeServer.port }.build() } private val job = SupervisorJob() - var port: Int = 0 + public var port: Int = 0 - lateinit var server: ServerSocket - lateinit var selector: SelectorManager + public lateinit var server: ServerSocket + public lateinit var selector: SelectorManager - fun start(): AndroidDebugBridgeClient { + public fun start(): AndroidDebugBridgeClient { val address = InetSocketAddress("127.0.0.1", port) selector = SelectorManager(Dispatchers.IO) server = runBlocking { aSocket(selector).tcp().bind(address) } @@ -69,14 +69,14 @@ class AndroidDebugBridgeServer : CoroutineScope { return client } - fun session(block: suspend Session.() -> Unit) { + public fun session(block: suspend Session.() -> Unit) { listen { input, output -> val session = Session(input, output) block(session) } } - fun multipleSessions(block: suspend Expectation.() -> Unit) { + public fun multipleSessions(block: suspend Expectation.() -> Unit) { async(context = job) { val expectation = Expectation() block(expectation) @@ -101,7 +101,7 @@ class AndroidDebugBridgeServer : CoroutineScope { } } - fun listen(block: suspend (input: ServerReadChannel, output: ServerWriteChannel) -> Unit) { + public fun listen(block: suspend (input: ServerReadChannel, output: ServerWriteChannel) -> Unit) { async(context = job) { try { val socket = server.accept() @@ -122,7 +122,7 @@ class AndroidDebugBridgeServer : CoroutineScope { } } - suspend fun dispose() { + public suspend fun dispose() { if (job.isActive) { job.complete() job.children.iterator().forEach { diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ConsoleReadChannel.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ConsoleReadChannel.kt index 8fe5a52bc..9e652e384 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ConsoleReadChannel.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ConsoleReadChannel.kt @@ -22,8 +22,8 @@ import assertk.assertions.startsWith import io.ktor.utils.io.ByteReadChannel import io.ktor.utils.io.readLine -class ConsoleReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel by delegate { - suspend fun receiveCommand() = delegate.readLine()!! - suspend fun receiveAuth() = receiveCommand().apply { assertThat(this).startsWith("auth ") }.substringAfter("auth ") - suspend fun receiveExit() = receiveCommand().apply { assertThat(this).isEqualTo("quit") } +public class ConsoleReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel by delegate { + public suspend fun receiveCommand(): String = delegate.readLine()!! + public suspend fun receiveAuth(): String = receiveCommand().apply { assertThat(this).startsWith("auth ") }.substringAfter("auth ") + public suspend fun receiveExit(): String = receiveCommand().apply { assertThat(this).isEqualTo("quit") } } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ConsoleWriteChannel.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ConsoleWriteChannel.kt index 026df0f08..0e4071603 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ConsoleWriteChannel.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ConsoleWriteChannel.kt @@ -19,8 +19,8 @@ package com.malinskiy.adam.server.stub import io.ktor.utils.io.ByteWriteChannel import io.ktor.utils.io.writeStringUtf8 -class ConsoleWriteChannel(private val delegate: ByteWriteChannel) : ByteWriteChannel by delegate { - suspend fun writeAuth() { +public class ConsoleWriteChannel(private val delegate: ByteWriteChannel) : ByteWriteChannel by delegate { + public suspend fun writeAuth() { delegate.writeStringUtf8("Android Console: Authentication required") delegate.writeStringUtf8("Android Console: type 'auth ' to authenticate") delegate.writeStringUtf8("Android Console: you can find your in") @@ -30,5 +30,7 @@ class ConsoleWriteChannel(private val delegate: ByteWriteChannel) : ByteWriteCha delegate.writeStringUtf8("OK\r\n") } - suspend fun respond(message: String) = delegate.writeStringUtf8(message) + public suspend fun respond(message: String) { + delegate.writeStringUtf8(message) + } } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/EmulatorConsoleServer.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/EmulatorConsoleServer.kt index 589e94196..545fadebe 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/EmulatorConsoleServer.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/EmulatorConsoleServer.kt @@ -39,7 +39,7 @@ import java.io.Closeable import kotlin.coroutines.CoroutineContext import java.net.InetSocketAddress as JavaInetSocketAddress -class EmulatorConsoleServer : CoroutineScope, Closeable { +public class EmulatorConsoleServer : CoroutineScope, Closeable { private val executionDispatcher by lazy { newFixedThreadPoolContext(4, "EmulatorConsoleServer") } @@ -47,9 +47,9 @@ class EmulatorConsoleServer : CoroutineScope, Closeable { get() = executionDispatcher private val job = SupervisorJob() - var port: Int = 0 + public var port: Int = 0 - suspend fun startAndListen(block: suspend (ConsoleReadChannel, ConsoleWriteChannel) -> Unit): Pair { + public suspend fun startAndListen(block: suspend (ConsoleReadChannel, ConsoleWriteChannel) -> Unit): Pair { val address = InetSocketAddress("127.0.0.1", port) val server = aSocket(SelectorManager(Dispatchers.IO)).tcp().bind(address) port = server.localAddress.toJavaAddress().port @@ -74,7 +74,7 @@ class EmulatorConsoleServer : CoroutineScope, Closeable { return Pair(AndroidDebugBridgeClientFactory().build(), JavaInetSocketAddress(address.hostname, port)) } - override fun close() = runBlocking { + override fun close(): Unit = runBlocking { job.cancelAndJoin() } } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerReadChannel.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerReadChannel.kt index 9ffd491dc..2f8959433 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerReadChannel.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerReadChannel.kt @@ -33,17 +33,17 @@ import kotlinx.coroutines.Job import java.io.File import kotlin.coroutines.coroutineContext -class ServerReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel by delegate { +public class ServerReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel by delegate { - suspend fun readByte(): Byte = delegate.channelReadByte() + public suspend fun readByte(): Byte = delegate.channelReadByte() - suspend fun readIntLittleEndian(): Int = Integer.reverseBytes(delegate.channelReadInt()) + public suspend fun readIntLittleEndian(): Int = Integer.reverseBytes(delegate.channelReadInt()) - suspend fun readFully(dst: ByteArray, offset: Int, length: Int) { + public suspend fun readFully(dst: ByteArray, offset: Int, length: Int) { val tmp = delegate.readByteArray(length) System.arraycopy(tmp, 0, dst, offset, length) } - suspend fun receiveCommand(): String { + public suspend fun receiveCommand(): String { val bytes = ByteArray(4) readFully(bytes, 0, 4) val length = String(bytes, Const.DEFAULT_TRANSPORT_ENCODING).toInt(16) @@ -52,13 +52,13 @@ class ServerReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel return String(request, Const.DEFAULT_TRANSPORT_ENCODING) } - suspend fun receiveBytes(length: Int): ByteArray { + public suspend fun receiveBytes(length: Int): ByteArray { val bytes = ByteArray(length) readFully(bytes, 0, length) return bytes } - suspend fun receiveStat(): String { + public suspend fun receiveStat(): String { val protocolMessage = receiveProtocolMessage() val message = String(protocolMessage, Const.DEFAULT_TRANSPORT_ENCODING) if (message != "STAT") throw RuntimeException( @@ -70,7 +70,7 @@ class ServerReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel return String(request, Const.DEFAULT_TRANSPORT_ENCODING) } - suspend fun receiveStatV2(): String { + public suspend fun receiveStatV2(): String { val protocolMessage = receiveProtocolMessage() val message = String(protocolMessage, Const.DEFAULT_TRANSPORT_ENCODING) if (message != "LST2") throw RuntimeException( @@ -82,7 +82,7 @@ class ServerReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel return String(request, Const.DEFAULT_TRANSPORT_ENCODING) } - suspend fun receiveList(): String { + public suspend fun receiveList(): String { val protocolMessage = receiveProtocolMessage() val message = String(protocolMessage, Const.DEFAULT_TRANSPORT_ENCODING) if (message != "LIST") throw RuntimeException( @@ -94,7 +94,7 @@ class ServerReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel return String(request, Const.DEFAULT_TRANSPORT_ENCODING) } - suspend fun receiveListV2(): String { + public suspend fun receiveListV2(): String { val protocolMessage = receiveProtocolMessage() val message = String(protocolMessage, Const.DEFAULT_TRANSPORT_ENCODING) if (message != "LIS2") throw RuntimeException( @@ -106,7 +106,7 @@ class ServerReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel return String(request, Const.DEFAULT_TRANSPORT_ENCODING) } - suspend fun receiveSend(): String { + public suspend fun receiveSend(): String { val protocolMessage = receiveProtocolMessage() val message = String(protocolMessage, Const.DEFAULT_TRANSPORT_ENCODING) if (message != "SEND") throw RuntimeException( @@ -118,7 +118,7 @@ class ServerReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel return String(request, Const.DEFAULT_TRANSPORT_ENCODING) } - suspend fun receiveSendV2(): Triple { + public suspend fun receiveSendV2(): Triple { val protocolMessage = receiveProtocolMessage() var message = String(protocolMessage, Const.DEFAULT_TRANSPORT_ENCODING) if (message != "SND2") throw RuntimeException( @@ -137,13 +137,13 @@ class ServerReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel return Triple(String(request, Const.DEFAULT_TRANSPORT_ENCODING), mode, flags) } - suspend fun receiveProtocolMessage(): ByteArray { + public suspend fun receiveProtocolMessage(): ByteArray { val bytes = ByteArray(4) readFully(bytes, 0, 4) return bytes } - suspend fun receiveRecv(): String { + public suspend fun receiveRecv(): String { val protocolMessage = receiveProtocolMessage() val message = String(protocolMessage, Const.DEFAULT_TRANSPORT_ENCODING) if (message != "RECV") throw RuntimeException( @@ -156,7 +156,7 @@ class ServerReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel return String(request, Const.DEFAULT_TRANSPORT_ENCODING) } - suspend fun receiveRecv2(): String { + public suspend fun receiveRecv2(): String { val protocolMessage = receiveProtocolMessage() var message = String(protocolMessage, Const.DEFAULT_TRANSPORT_ENCODING) if (message != "RCV2") throw RuntimeException("Unexpected protocol message $message") @@ -175,7 +175,7 @@ class ServerReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel return String(request, Const.DEFAULT_TRANSPORT_ENCODING) } - suspend fun receiveFile(file: File): File { + public suspend fun receiveFile(file: File): File { val job = Job() val channel = file.writeChannel(coroutineContext + job) val headerBuffer = ByteArray(8) @@ -208,7 +208,7 @@ class ServerReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel } } - suspend fun receiveShellV2Stdin(): String { + public suspend fun receiveShellV2Stdin(): String { readByte().apply { assertThat(this).isEqualTo(MessageType.STDIN.toValue().toByte()) } val size = readIntLittleEndian() val request = ByteArray(size) @@ -216,7 +216,7 @@ class ServerReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel return String(request, Const.DEFAULT_TRANSPORT_ENCODING) } - suspend fun receiveShellV2StdinClose() { + public suspend fun receiveShellV2StdinClose() { readByte().apply { assertThat(this).isEqualTo(MessageType.CLOSE_STDIN.toValue().toByte()) } assertThat(readIntLittleEndian()).isEqualTo(0) } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerWriteChannel.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerWriteChannel.kt index 33872afd0..7b762e2b4 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerWriteChannel.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerWriteChannel.kt @@ -26,12 +26,12 @@ import io.ktor.utils.io.writeInt as channelWriteInt import io.ktor.utils.io.writeLong as channelWriteLong import io.ktor.utils.io.writeByte as channelWriteByte -class ServerWriteChannel(private val delegate: ByteWriteChannel) : ByteWriteChannel by delegate { +public class ServerWriteChannel(private val delegate: ByteWriteChannel) : ByteWriteChannel by delegate { private suspend fun write(request: ByteArray, length: Int? = null) { delegate.writeByteArray(request.copyOfRange(0, length ?: request.size)) } - suspend fun writeIntLittleEndian(value: Int) { + public suspend fun writeIntLittleEndian(value: Int) { delegate.channelWriteInt(Integer.reverseBytes(value)) } @@ -39,32 +39,34 @@ class ServerWriteChannel(private val delegate: ByteWriteChannel) : ByteWriteChan delegate.channelWriteLong(java.lang.Long.reverseBytes(value)) } - suspend fun writeFully(src: ByteArray) { + public suspend fun writeFully(src: ByteArray) { delegate.writeByteArray(src) } - suspend fun writeFully(src: ByteArray, offset: Int, length: Int) { + public suspend fun writeFully(src: ByteArray, offset: Int, length: Int) { delegate.writeByteArray(src.copyOfRange(offset, offset + length)) } - suspend fun writeByte(value: Byte) { + public suspend fun writeByte(value: Byte) { delegate.channelWriteByte(value) } - suspend fun respond(request: ByteArray, length: Int? = null) = write(request, length) + public suspend fun respond(request: ByteArray, length: Int? = null) { + write(request, length) + } - suspend fun respondOkay() { + public suspend fun respondOkay() { respond(Const.Message.OKAY) } - suspend fun respondStat(size: Int, mode: Int = 0, lastModified: Int = 0) { + public suspend fun respondStat(size: Int, mode: Int = 0, lastModified: Int = 0) { respond(Const.Message.LSTAT_V1) writeIntLittleEndian(mode) writeIntLittleEndian(size) writeIntLittleEndian(lastModified) } - suspend fun respondStatV2( + public suspend fun respondStatV2( mode: Int, size: Int, error: Int, @@ -91,25 +93,25 @@ class ServerWriteChannel(private val delegate: ByteWriteChannel) : ByteWriteChan writeLongLittleEndian(ctime.toLong()) } - suspend fun respondData(byteArray: ByteArray) { + public suspend fun respondData(byteArray: ByteArray) { respond(Const.Message.DATA) writeIntLittleEndian(byteArray.size) writeFully(byteArray, 0, byteArray.size) } - suspend fun respondDone() { + public suspend fun respondDone() { respond(Const.Message.DONE) } - suspend fun respondDoneDone() { + public suspend fun respondDoneDone() { respond(Const.Message.DONEDONE) } - suspend fun respondFailFail() { + public suspend fun respondFailFail() { respond(Const.Message.FAILFAIL) } - suspend fun respondList(size: Int, mode: Int = 0, lastModified: Int = 0, name: String) { + public suspend fun respondList(size: Int, mode: Int = 0, lastModified: Int = 0, name: String) { respond(Const.Message.DENT_V1) writeIntLittleEndian(mode) writeIntLittleEndian(size) @@ -118,7 +120,7 @@ class ServerWriteChannel(private val delegate: ByteWriteChannel) : ByteWriteChan writeStringUtf8(name) } - suspend fun respondListV2( + public suspend fun respondListV2( name: String, mode: Int = 0, size: Int, @@ -148,7 +150,7 @@ class ServerWriteChannel(private val delegate: ByteWriteChannel) : ByteWriteChan writeStringUtf8(name) } - suspend fun respondStringV1(message: String) { + public suspend fun respondStringV1(message: String) { val lengthString = message.length.toString(16) val prepend = 4 - lengthString.length assert(prepend >= 0) @@ -161,53 +163,53 @@ class ServerWriteChannel(private val delegate: ByteWriteChannel) : ByteWriteChan writeFully(message.toByteArray(Const.DEFAULT_TRANSPORT_ENCODING)) } - suspend fun respondStringV2(message: String) { + public suspend fun respondStringV2(message: String) { val bytes = message.toByteArray(Const.DEFAULT_TRANSPORT_ENCODING) writeIntLittleEndian(bytes.size) writeFully(bytes) } - suspend fun respondStringRaw(message: String) { + public suspend fun respondStringRaw(message: String) { respond(message.toByteArray(Const.DEFAULT_TRANSPORT_ENCODING)) } - suspend fun respondFail(message: String) { + public suspend fun respondFail(message: String) { respond(Const.Message.FAIL) writeIntLittleEndian(message.length) respondStringRaw(message) } - suspend fun respondShellV1(stdout: String) { + public suspend fun respondShellV1(stdout: String) { respondStringRaw(stdout) } - suspend fun respondShellV2(stdout: String, stderr: String, exitCode: Int) { + public suspend fun respondShellV2(stdout: String, stderr: String, exitCode: Int) { respondShellV2Stdout(stdout) respondShellV2Stderr(stderr) respondShellV2Exit(exitCode) } - suspend fun respondShellV2Exit(exitCode: Int) { + public suspend fun respondShellV2Exit(exitCode: Int) { delegate.channelWriteByte(MessageType.EXIT.toValue().toByte()) delegate.channelWriteInt(1) delegate.channelWriteByte(exitCode.toByte()) } - suspend fun respondShellV2Stderr(stderr: String) { + public suspend fun respondShellV2Stderr(stderr: String) { delegate.channelWriteByte(MessageType.STDERR.toValue().toByte()) respondStringV2(stderr) } - suspend fun respondShellV2Stdout(stdout: String) { + public suspend fun respondShellV2Stdout(stdout: String) { delegate.channelWriteByte(MessageType.STDOUT.toValue().toByte()) respondStringV2(stdout) } - suspend fun respondShellV2WindowSizeChange() { + public suspend fun respondShellV2WindowSizeChange() { delegate.channelWriteByte(MessageType.WINDOW_SIZE_CHANGE.toValue().toByte()) } - suspend fun respondShellV2Invalid() { + public suspend fun respondShellV2Invalid() { delegate.channelWriteByte(MessageType.INVALID.toValue().toByte()) } } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/StubSocket.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/StubSocket.kt index e0785145e..356bf6297 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/StubSocket.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/StubSocket.kt @@ -29,16 +29,16 @@ import java.nio.ByteBuffer import io.ktor.utils.io.readByte as channelReadByte import io.ktor.utils.io.writeByte as channelWriteByte -class StubSocket( - val readChannel: ByteReadChannel = ByteChannel(false), - val writeChannel: ByteWriteChannel = ByteChannel(false) +public class StubSocket( + public val readChannel: ByteReadChannel = ByteChannel(false), + public val writeChannel: ByteWriteChannel = ByteChannel(false) ) : Socket { override val isClosedForWrite: Boolean get() = writeChannel.isClosedForWrite override val isClosedForRead: Boolean get() = readChannel.isClosedForRead - constructor(content: ByteArray) : this(readChannel = ByteReadChannel(content)) + public constructor(content: ByteArray) : this(readChannel = ByteReadChannel(content)) override suspend fun readFully(buffer: ByteBuffer): Int { val count = buffer.remaining() @@ -71,8 +71,8 @@ class StubSocket( override suspend fun readByte(): Byte = readChannel.channelReadByte() override suspend fun readIntLittleEndian(): Int = Integer.reverseBytes(readChannel.readInt()) - override suspend fun writeByte(value: Int) = writeChannel.channelWriteByte(value.toByte()) - override suspend fun writeIntLittleEndian(value: Int) = writeChannel.writeInt(Integer.reverseBytes(value)) + override suspend fun writeByte(value: Int): Unit = writeChannel.channelWriteByte(value.toByte()) + override suspend fun writeIntLittleEndian(value: Int): Unit = writeChannel.writeInt(Integer.reverseBytes(value)) override suspend fun close() { try { diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/DeviceExpectation.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/DeviceExpectation.kt index 184127b00..095c948cc 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/DeviceExpectation.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/DeviceExpectation.kt @@ -16,15 +16,15 @@ package com.malinskiy.adam.server.stub.dsl -data class DeviceExpectation( - val serialNo: String, +public data class DeviceExpectation( + public val serialNo: String, private val list: MutableList Unit> = mutableListOf() ) { - fun session(block: suspend Session.() -> Unit) { + public fun session(block: suspend Session.() -> Unit) { list.add(block) } - suspend fun handle(session: Session) { + public suspend fun handle(session: Session) { assert(list.size > 0) { "No handles registered for request" } val head = list.removeAt(0) head(session) diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/DoneFailSubSession.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/DoneFailSubSession.kt index f09b9cd37..5937e45f3 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/DoneFailSubSession.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/DoneFailSubSession.kt @@ -16,12 +16,12 @@ package com.malinskiy.adam.server.stub.dsl -class DoneFailSubSession(private val session: Session) { - suspend fun done() { +public class DoneFailSubSession(private val session: Session) { + public suspend fun done() { session.output.respondDone() } - suspend fun fail(message: String) { + public suspend fun fail(message: String) { session.output.respondFail(message) } } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/ExecSubSession.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/ExecSubSession.kt index 265ef5780..9f7b9658d 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/ExecSubSession.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/ExecSubSession.kt @@ -18,23 +18,23 @@ package com.malinskiy.adam.server.stub.dsl import java.io.File -class ExecSubSession(private val session: Session) { - suspend fun accept(): ExecSubSession { +public class ExecSubSession(private val session: Session) { + public suspend fun accept(): ExecSubSession { session.respondOkay() return this } - suspend fun respond(stdout: String): ExecSubSession { + public suspend fun respond(stdout: String): ExecSubSession { session.respondShellV1(stdout) return this } - suspend fun receiveFile(fixture: File): ExecSubSession { + public suspend fun receiveFile(fixture: File): ExecSubSession { session.expectBytesAsFile(fixture) return this } - suspend fun reject(message: String) { + public suspend fun reject(message: String) { session.respondTransport(false, message) } } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Expectation.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Expectation.kt index 5714a6920..2b8da5f7c 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Expectation.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Expectation.kt @@ -16,22 +16,22 @@ package com.malinskiy.adam.server.stub.dsl -class Expectation { +public class Expectation { private val handlers = mutableMapOf() private var otherHandlers = mutableMapOf Unit>() - fun serial(serialNo: String, block: DeviceExpectation.() -> Unit) { + public fun serial(serialNo: String, block: DeviceExpectation.() -> Unit) { val deviceExpectation = handlers[serialNo] ?: DeviceExpectation(serialNo) handlers[serialNo] = deviceExpectation block(deviceExpectation) } - fun other(transportString: String, block: suspend Session.() -> Unit) { + public fun other(transportString: String, block: suspend Session.() -> Unit) { assert(!otherHandlers.contains(transportString)) { "Handler for $transportString already exists" } otherHandlers[transportString] = block } - suspend fun select(session: Session): Boolean { + public suspend fun select(session: Session): Boolean { val transportCmd = session.input.receiveCommand() return if (transportCmd.startsWith("host:transport:")) { val serial = transportCmd.substringAfter("host:transport:") diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/FramebufferSubSession.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/FramebufferSubSession.kt index d840cf841..069f5af23 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/FramebufferSubSession.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/FramebufferSubSession.kt @@ -18,22 +18,22 @@ package com.malinskiy.adam.server.stub.dsl import java.io.File -class FramebufferSubSession(private val session: Session) { - suspend fun accept(): FramebufferSubSession { +public class FramebufferSubSession(private val session: Session) { + public suspend fun accept(): FramebufferSubSession { session.respondTransport(true) return this } - suspend fun reject(message: String): FramebufferSubSession { + public suspend fun reject(message: String): FramebufferSubSession { session.respondTransport(false, message) return this } - suspend fun respondScreencaptureV2(replay: File) { + public suspend fun respondScreencaptureV2(replay: File) { session.respondScreencaptureV2(replay) } - suspend fun respondScreencaptureV3(replay: File) { + public suspend fun respondScreencaptureV3(replay: File) { session.respondScreencaptureV3(replay) } } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/GetAdbServerSubSession.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/GetAdbServerSubSession.kt index a354f64ab..3be7612a0 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/GetAdbServerSubSession.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/GetAdbServerSubSession.kt @@ -16,18 +16,18 @@ package com.malinskiy.adam.server.stub.dsl -class GetAdbServerSubSession(private val session: Session) { - suspend fun accept(): GetAdbServerSubSession { +public class GetAdbServerSubSession(private val session: Session) { + public suspend fun accept(): GetAdbServerSubSession { session.respondTransport(true) return this } - suspend fun reject(message: String): GetAdbServerSubSession { + public suspend fun reject(message: String): GetAdbServerSubSession { session.respondTransport(false, message) return this } - suspend fun respondAdbServerVersion(version: Int) { + public suspend fun respondAdbServerVersion(version: Int) { session.respondAdbServerVersion(version) } } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/LegacySideloadSubSession.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/LegacySideloadSubSession.kt index 6a7dbc7ab..f5decb7a5 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/LegacySideloadSubSession.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/LegacySideloadSubSession.kt @@ -16,17 +16,17 @@ package com.malinskiy.adam.server.stub.dsl -class LegacySideloadSubSession(private val session: Session) { - suspend fun receive(size: Int): LegacySideloadSubSession { +public class LegacySideloadSubSession(private val session: Session) { + public suspend fun receive(size: Int): LegacySideloadSubSession { session.receiveBytes(size) return this } - suspend fun okay() { + public suspend fun okay() { session.respondOkay() } - suspend fun fail(message: String) { + public suspend fun fail(message: String) { session.respondTransport(false, message) } } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/OkayFailSubSession.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/OkayFailSubSession.kt index 891109d50..10bebe310 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/OkayFailSubSession.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/OkayFailSubSession.kt @@ -16,13 +16,13 @@ package com.malinskiy.adam.server.stub.dsl -open class OkayFailSubSession(private val session: Session) { - suspend fun accept(): OkayFailSubSession { +public open class OkayFailSubSession(private val session: Session) { + public suspend fun accept(): OkayFailSubSession { session.respondTransport(true) return this } - suspend fun reject(message: String): OkayFailSubSession { + public suspend fun reject(message: String): OkayFailSubSession { session.respondTransport(false, message) return this } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/ReceiveFileSubSession.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/ReceiveFileSubSession.kt index 5888f39b3..4f119b548 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/ReceiveFileSubSession.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/ReceiveFileSubSession.kt @@ -18,13 +18,13 @@ package com.malinskiy.adam.server.stub.dsl import java.io.File -class ReceiveFileSubSession(private val session: Session) { - suspend fun respondFile(fixture: File): ReceiveFileSubSession { +public class ReceiveFileSubSession(private val session: Session) { + public suspend fun respondFile(fixture: File): ReceiveFileSubSession { session.respondFile(fixture) return this } - suspend fun respondDoneDone() { + public suspend fun respondDoneDone() { session.output.respondDoneDone() } } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/SendFileSubSession.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/SendFileSubSession.kt index 8eb3cd5a3..9b1766098 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/SendFileSubSession.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/SendFileSubSession.kt @@ -19,17 +19,17 @@ package com.malinskiy.adam.server.stub.dsl import com.malinskiy.adam.Const import java.io.File -class SendFileSubSession(private val session: Session) { - suspend fun receiveFile(fixture: File): SendFileSubSession { +public class SendFileSubSession(private val session: Session) { + public suspend fun receiveFile(fixture: File): SendFileSubSession { session.receiveFile(fixture) return this } - suspend fun done() { + public suspend fun done() { session.respondOkay() } - suspend fun fail(message: String) { + public suspend fun fail(message: String) { session.output.respond(Const.Message.FAIL) session.output.respondStringV1(message) } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/SendFileV2SubSession.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/SendFileV2SubSession.kt index c69316d41..32726cffb 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/SendFileV2SubSession.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/SendFileV2SubSession.kt @@ -19,17 +19,17 @@ package com.malinskiy.adam.server.stub.dsl import com.malinskiy.adam.Const import java.io.File -class SendFileV2SubSession(private val session: Session) { - suspend fun receiveFile(fixture: File): SendFileV2SubSession { +public class SendFileV2SubSession(private val session: Session) { + public suspend fun receiveFile(fixture: File): SendFileV2SubSession { session.receiveFile(fixture) return this } - suspend fun done() { + public suspend fun done() { session.respondOkay() } - suspend fun fail(message: String) { + public suspend fun fail(message: String) { session.output.respond(Const.Message.FAIL) session.output.respondStringV2(message) } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Session.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Session.kt index 8df1f9d08..a55c2e56a 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Session.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Session.kt @@ -24,33 +24,33 @@ import com.malinskiy.adam.server.stub.ServerWriteChannel import java.io.File -class Session(val input: ServerReadChannel, val output: ServerWriteChannel) { - suspend fun expectCmd(expected: () -> String): OkayFailSubSession { +public class Session(public val input: ServerReadChannel, public val output: ServerWriteChannel) { + public suspend fun expectCmd(expected: () -> String): OkayFailSubSession { val transportCmd = input.receiveCommand() assertThat(transportCmd).isEqualTo(expected()) return OkayFailSubSession(session = this) } - suspend fun expectShell(expected: () -> String): ShellV1SubSession { + public suspend fun expectShell(expected: () -> String): ShellV1SubSession { val transportCmd = input.receiveCommand() assertThat(transportCmd).isEqualTo("shell:${expected()}") return ShellV1SubSession(session = this) } - suspend fun expectShellV2(expected: () -> String): ShellV2SubSession { + public suspend fun expectShellV2(expected: () -> String): ShellV2SubSession { val transportCmd = input.receiveCommand() assertThat(transportCmd).isEqualTo("shell,v2,raw:${expected()}") return ShellV2SubSession(session = this) } - suspend fun expectExec(expected: () -> String): ExecSubSession { + public suspend fun expectExec(expected: () -> String): ExecSubSession { val transportCmd = input.receiveCommand() assertThat(transportCmd).isEqualTo("exec:${expected()}") return ExecSubSession(session = this) } - suspend fun respondTransport(success: Boolean, message: String? = null) { + public suspend fun respondTransport(success: Boolean, message: String? = null) { output.respond( when (success) { true -> Const.Message.OKAY @@ -63,16 +63,16 @@ class Session(val input: ServerReadChannel, val output: ServerWriteChannel) { } } - suspend fun respondShellV1(stdout: String) { + public suspend fun respondShellV1(stdout: String) { output.respondShellV1(stdout) } - suspend fun expectFramebuffer(): FramebufferSubSession { + public suspend fun expectFramebuffer(): FramebufferSubSession { expectCmd { "framebuffer:" } return FramebufferSubSession(this) } - suspend fun respondScreencaptureV2(replay: File) { + public suspend fun respondScreencaptureV2(replay: File) { //Extended version output.writeIntLittleEndian(1) @@ -82,7 +82,7 @@ class Session(val input: ServerReadChannel, val output: ServerWriteChannel) { output.writeFully(sample, 48, sample.size - 48) } - suspend fun respondScreencaptureV3(replay: File) { + public suspend fun respondScreencaptureV3(replay: File) { //Extended version output.writeIntLittleEndian(2) @@ -92,31 +92,31 @@ class Session(val input: ServerReadChannel, val output: ServerWriteChannel) { output.writeFully(sample, 52, sample.size - 52) } - suspend fun respondAdbServerVersion(x: Int) { + public suspend fun respondAdbServerVersion(x: Int) { output.respondStringV1(x.toString(16)) } - suspend fun respondPairDevice(message: String) { + public suspend fun respondPairDevice(message: String) { output.respondStringV1(message) } - suspend fun respondReconnectOffline(message: String) { + public suspend fun respondReconnectOffline(message: String) { output.respondStringV1(message) } - suspend fun respondReconnectSingleDevice(message: String) { + public suspend fun respondReconnectSingleDevice(message: String) { output.respondStringRaw(message) } - suspend fun respondRemountPartitions(message: () -> String) { + public suspend fun respondRemountPartitions(message: () -> String) { output.respondStringRaw(message()) } - suspend fun respondSideloadChunkRequested(part: String) { + public suspend fun respondSideloadChunkRequested(part: String) { output.respondStringRaw(part) } - suspend fun respondPortForward(success: Boolean, port: Int? = null) { + public suspend fun respondPortForward(success: Boolean, port: Int? = null) { output.respond( when (success) { true -> Const.Message.OKAY @@ -129,49 +129,49 @@ class Session(val input: ServerReadChannel, val output: ServerWriteChannel) { } } - suspend fun respondSetDmVerityChecking(message: String) { + public suspend fun respondSetDmVerityChecking(message: String) { output.respondStringRaw(message) } - suspend fun expectShellV2Stdin(expected: String) { + public suspend fun expectShellV2Stdin(expected: String) { val stdin = input.receiveShellV2Stdin() assertThat(stdin).isEqualTo(expected) } - suspend fun expectShellV2StdinClose() { + public suspend fun expectShellV2StdinClose() { input.receiveShellV2StdinClose() } - suspend fun respondShellV2Stdout(message: String) { + public suspend fun respondShellV2Stdout(message: String) { output.respondShellV2Stdout(message) } - suspend fun respondShellV2Exit(exitCode: Int) { + public suspend fun respondShellV2Exit(exitCode: Int) { output.respondShellV2Exit(exitCode) } - suspend fun respondShellV2Stderr(stderr: String) { + public suspend fun respondShellV2Stderr(stderr: String) { output.respondShellV2Stderr(stderr) } - suspend fun respondShellV2WindowSizeChange() { + public suspend fun respondShellV2WindowSizeChange() { output.respondShellV2WindowSizeChange() } - suspend fun respondShellV2Invalid() { + public suspend fun respondShellV2Invalid() { output.respondShellV2Invalid() } - suspend fun expectStat(path: () -> String) { + public suspend fun expectStat(path: () -> String) { val receiveStat = input.receiveStat() assertThat(receiveStat).isEqualTo(path()) } - suspend fun respondStat(size: Int, mode: Int = 0, lastModified: Int = 0) { + public suspend fun respondStat(size: Int, mode: Int = 0, lastModified: Int = 0) { output.respondStat(size, mode, lastModified) } - suspend fun respondStatV2( + public suspend fun respondStatV2( mode: Int, size: Int, error: Int, @@ -187,18 +187,18 @@ class Session(val input: ServerReadChannel, val output: ServerWriteChannel) { output.respondStatV2(mode, size, error, dev, ino, nlink, uid, gid, atime, mtime, ctime) } - suspend fun expectSend(message: () -> String): SendFileSubSession { + public suspend fun expectSend(message: () -> String): SendFileSubSession { val receiveCmd = input.receiveSend() assertThat(receiveCmd).isEqualTo(message()) return SendFileSubSession(this) } - suspend fun receiveFile(receiveFile: File) { + public suspend fun receiveFile(receiveFile: File) { input.receiveFile(receiveFile) } - suspend fun expectSendV2(receiveCmd: String, mode: String, flags: Int): SendFileV2SubSession { + public suspend fun expectSendV2(receiveCmd: String, mode: String, flags: Int): SendFileV2SubSession { val (actualReceiveCmd, actualMode, actualFlags) = input.receiveSendV2() assertThat(actualReceiveCmd).isEqualTo(receiveCmd) assertThat(actualMode.toString(8)).isEqualTo(mode) @@ -207,39 +207,39 @@ class Session(val input: ServerReadChannel, val output: ServerWriteChannel) { return SendFileV2SubSession(this) } - suspend fun expectRecv(path: () -> String): ReceiveFileSubSession { + public suspend fun expectRecv(path: () -> String): ReceiveFileSubSession { val recvPath = input.receiveRecv() assertThat(recvPath).isEqualTo(path()) return ReceiveFileSubSession(this) } - suspend fun respondFile(fixture: File) { + public suspend fun respondFile(fixture: File) { output.respondData(fixture.readBytes()) } - suspend fun expectRecv2(path: () -> String): ReceiveFileSubSession { + public suspend fun expectRecv2(path: () -> String): ReceiveFileSubSession { val recvPath = input.receiveRecv2() assertThat(recvPath).isEqualTo(path()) return ReceiveFileSubSession(this) } - suspend fun expectList(path: () -> String) { + public suspend fun expectList(path: () -> String) { val listPath = input.receiveList() assertThat(listPath).isEqualTo(path()) } - suspend fun respondList(size: Int, mode: Int = 0, lastModified: Int = 0, name: String): DoneFailSubSession { + public suspend fun respondList(size: Int, mode: Int = 0, lastModified: Int = 0, name: String): DoneFailSubSession { output.respondList(size, mode, lastModified, name) return DoneFailSubSession(this) } - suspend fun expectListV2(path: () -> String) { + public suspend fun expectListV2(path: () -> String) { val listPath = input.receiveListV2() assertThat(listPath).isEqualTo(path()) } - suspend fun respondListV2( + public suspend fun respondListV2( name: String, mode: Int = 0, size: Int, @@ -257,56 +257,56 @@ class Session(val input: ServerReadChannel, val output: ServerWriteChannel) { return DoneFailSubSession(this) } - suspend fun expectStatV2(path: () -> String) { + public suspend fun expectStatV2(path: () -> String) { val receiveStat = input.receiveStatV2() assertThat(receiveStat).isEqualTo(path()) } - suspend fun resondRestartAdbd(message: String) { + public suspend fun resondRestartAdbd(message: String) { output.respondStringRaw(message) } - suspend fun respondAsyncDeviceMonitor(serial: String, state: String) { + public suspend fun respondAsyncDeviceMonitor(serial: String, state: String) { output.respondStringV1("$serial\t$state\n") } - suspend fun respondListDevices(serialToState: Map) { + public suspend fun respondListDevices(serialToState: Map) { val response = serialToState.map { "${it.key}\t${it.value}\n" }.joinToString(separator = "") output.respondStringV1(response) } - suspend fun respondListPortForwards(response: String) { + public suspend fun respondListPortForwards(response: String) { output.respondStringV1(response) } - suspend fun respondConnectDevice(response: String) { + public suspend fun respondConnectDevice(response: String) { output.respondStringV1(response) } - suspend fun respondDisconnectDevice(response: String) { + public suspend fun respondDisconnectDevice(response: String) { output.respondStringV1(response) } - suspend fun respondOkay() { + public suspend fun respondOkay() { output.respondOkay() } - suspend fun expectLegacySideload(size: Int): LegacySideloadSubSession { + public suspend fun expectLegacySideload(size: Int): LegacySideloadSubSession { expectCmd { "sideload:$size" }.accept() return LegacySideloadSubSession(this) } - suspend fun receiveBytes(size: Int): ByteArray { + public suspend fun receiveBytes(size: Int): ByteArray { return input.receiveBytes(size) } - suspend fun expectBytesAsFile(expected: File) { + public suspend fun expectBytesAsFile(expected: File) { val actual = receiveBytes(expected.length().toInt()) assertThat(actual).isEqualTo(expected.readBytes()) } - suspend fun expectAdbServerVersion(): GetAdbServerSubSession { + public suspend fun expectAdbServerVersion(): GetAdbServerSubSession { expectCmd { "host:version" } return GetAdbServerSubSession(this) } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/ShellV1SubSession.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/ShellV1SubSession.kt index 6ba6fc3e9..be22242c7 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/ShellV1SubSession.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/ShellV1SubSession.kt @@ -16,18 +16,18 @@ package com.malinskiy.adam.server.stub.dsl -class ShellV1SubSession(private val session: Session) { - suspend fun accept(): ShellV1SubSession { +public class ShellV1SubSession(private val session: Session) { + public suspend fun accept(): ShellV1SubSession { session.respondOkay() return this } - suspend fun respond(stdout: String): ShellV1SubSession { + public suspend fun respond(stdout: String): ShellV1SubSession { session.respondShellV1(stdout) return this } - suspend fun reject(message: String) { + public suspend fun reject(message: String) { session.respondTransport(false, message) } } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/ShellV2SubSession.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/ShellV2SubSession.kt index 895a99df8..740215316 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/ShellV2SubSession.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/ShellV2SubSession.kt @@ -16,28 +16,28 @@ package com.malinskiy.adam.server.stub.dsl -class ShellV2SubSession(private val session: Session) { - suspend fun accept(): ShellV2SubSession { +public class ShellV2SubSession(private val session: Session) { + public suspend fun accept(): ShellV2SubSession { session.respondOkay() return this } - suspend fun respondStdout(stdout: String): ShellV2SubSession { + public suspend fun respondStdout(stdout: String): ShellV2SubSession { session.respondShellV2Stdout(stdout) return this } - suspend fun respondStderr(stdout: String): ShellV2SubSession { + public suspend fun respondStderr(stdout: String): ShellV2SubSession { session.respondShellV2Stderr(stdout) return this } - suspend fun respondExit(exitCode: Int): ShellV2SubSession { + public suspend fun respondExit(exitCode: Int): ShellV2SubSession { session.respondShellV2Exit(exitCode) return this } - suspend fun reject(message: String) { + public suspend fun reject(message: String) { session.respondTransport(false, message) } } diff --git a/transport-ktor/build.gradle.kts b/transport-ktor/build.gradle.kts index bea56bbf9..6ebd18af8 100644 --- a/transport-ktor/build.gradle.kts +++ b/transport-ktor/build.gradle.kts @@ -18,6 +18,10 @@ plugins { id("adam.jvm") } +kotlin { + explicitApi() +} + dependencies { implementation(project(":adam")) implementation(libs.ktor.network) diff --git a/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocket.kt b/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocket.kt index f6a1ad1bf..cc0214237 100644 --- a/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocket.kt +++ b/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocket.kt @@ -33,7 +33,7 @@ import io.ktor.network.sockets.Socket as RealKtorSocket import io.ktor.utils.io.readByte as ktorReadByte import io.ktor.utils.io.writeByte as ktorWriteByte -class KtorSocket(private val ktorSocket: RealKtorSocket) : Socket { +public class KtorSocket(private val ktorSocket: RealKtorSocket) : Socket { private val readChannel: ByteReadChannel = ktorSocket.openReadChannel() private val writeChannel: ByteWriteChannel = ktorSocket.openWriteChannel(autoFlush = true) override val isClosedForWrite: Boolean @@ -99,7 +99,7 @@ class KtorSocket(private val ktorSocket: RealKtorSocket) : Socket { } } - companion object { + private companion object { private val log = AdamLogging.logger {} } } diff --git a/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketFactory.kt b/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketFactory.kt index a212f060b..36ec11e12 100644 --- a/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketFactory.kt +++ b/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketFactory.kt @@ -25,7 +25,7 @@ import kotlin.coroutines.CoroutineContext import io.ktor.network.sockets.InetSocketAddress as KtorSocketAddress @Deprecated(message = "Deprecated due to stability and performance issues") -class KtorSocketFactory( +public class KtorSocketFactory( coroutineContext: CoroutineContext, private val connectTimeout: Long = 10_000, private val idleTimeout: Long = 30_000 From 17ff8c71f400a41d353e2e23cfab2cf26a4bbf84 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sat, 14 Feb 2026 17:08:42 +0000 Subject: [PATCH 09/50] chore: move the declaration of explicit api to adam.jvm plugin --- adam/build.gradle.kts | 4 ---- buildSrc/src/main/kotlin/adam.jvm.gradle.kts | 4 ++++ server/server-stub-junit4/build.gradle.kts | 5 ----- server/server-stub-junit5/build.gradle.kts | 4 ---- server/server-stub/build.gradle.kts | 5 ----- transport-ktor/build.gradle.kts | 4 ---- 6 files changed, 4 insertions(+), 22 deletions(-) diff --git a/adam/build.gradle.kts b/adam/build.gradle.kts index 6bfca34ba..e4bae4635 100644 --- a/adam/build.gradle.kts +++ b/adam/build.gradle.kts @@ -25,10 +25,6 @@ plugins { id("idea") } -kotlin { - explicitApi() -} - protobuf { protoc { artifact = "com.google.protobuf:protoc:${libs.versions.protobuf.get()}" diff --git a/buildSrc/src/main/kotlin/adam.jvm.gradle.kts b/buildSrc/src/main/kotlin/adam.jvm.gradle.kts index d94443022..45c2c53d9 100644 --- a/buildSrc/src/main/kotlin/adam.jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/adam.jvm.gradle.kts @@ -5,6 +5,10 @@ plugins { // id("adam.code.lint") } +kotlin { + explicitApi() +} + java { sourceCompatibility = ProjectConfig.JavaVersion targetCompatibility = ProjectConfig.JavaVersion diff --git a/server/server-stub-junit4/build.gradle.kts b/server/server-stub-junit4/build.gradle.kts index 7ee8127c9..897fe3d6c 100644 --- a/server/server-stub-junit4/build.gradle.kts +++ b/server/server-stub-junit4/build.gradle.kts @@ -19,11 +19,6 @@ plugins { id("jacoco") } -kotlin { - explicitApi() -} - - tasks.jacocoTestReport { reports { xml.required.set(true) diff --git a/server/server-stub-junit5/build.gradle.kts b/server/server-stub-junit5/build.gradle.kts index 8d53cf5c8..931ea8a0d 100644 --- a/server/server-stub-junit5/build.gradle.kts +++ b/server/server-stub-junit5/build.gradle.kts @@ -19,10 +19,6 @@ plugins { id("jacoco") } -kotlin { - explicitApi() -} - tasks.jacocoTestReport { reports { xml.required.set(true) diff --git a/server/server-stub/build.gradle.kts b/server/server-stub/build.gradle.kts index c6ad7afff..37fab2ab4 100644 --- a/server/server-stub/build.gradle.kts +++ b/server/server-stub/build.gradle.kts @@ -19,11 +19,6 @@ plugins { id("jacoco") } -kotlin { - explicitApi() -} - - sourceSets { create("integrationTest") { compileClasspath += sourceSets.main.get().output diff --git a/transport-ktor/build.gradle.kts b/transport-ktor/build.gradle.kts index 6ebd18af8..bea56bbf9 100644 --- a/transport-ktor/build.gradle.kts +++ b/transport-ktor/build.gradle.kts @@ -18,10 +18,6 @@ plugins { id("adam.jvm") } -kotlin { - explicitApi() -} - dependencies { implementation(project(":adam")) implementation(libs.ktor.network) From e120787b623e57ea664ef6381f70ed453bf9cc0b Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sat, 14 Feb 2026 17:18:26 +0000 Subject: [PATCH 10/50] chore: enable explicit API in android library module --- .../junit4/android/listener/TestAnnotationProducer.kt | 2 +- .../com/malinskiy/adam/junit4/android/UnsafeAdbAccess.kt | 2 +- .../com/malinskiy/adam/junit4/android/rule/AdbRule.kt | 6 +++--- .../adam/junit4/android/rule/EmulatorConsoleRule.kt | 4 ++-- .../adam/junit4/android/rule/EmulatorGrpcRule.kt | 6 +++--- .../kotlin/com/malinskiy/adam/junit4/android/rule/Mode.kt | 2 +- .../rule/sandbox/SingleTargetAndroidDebugBridgeClient.kt | 8 ++++---- .../android/screencapture/AdamScreenCaptureProcessor.kt | 2 +- .../junit4/android/screencapture/AdamScreenCaptureRule.kt | 2 +- buildSrc/src/main/kotlin/adam.android.library.gradle.kts | 4 ++++ 10 files changed, 21 insertions(+), 17 deletions(-) diff --git a/android-junit4-test-annotation-producer/src/main/kotlin/com/malinskiy/adam/junit4/android/listener/TestAnnotationProducer.kt b/android-junit4-test-annotation-producer/src/main/kotlin/com/malinskiy/adam/junit4/android/listener/TestAnnotationProducer.kt index 23386da83..7528dfec4 100644 --- a/android-junit4-test-annotation-producer/src/main/kotlin/com/malinskiy/adam/junit4/android/listener/TestAnnotationProducer.kt +++ b/android-junit4-test-annotation-producer/src/main/kotlin/com/malinskiy/adam/junit4/android/listener/TestAnnotationProducer.kt @@ -42,7 +42,7 @@ import kotlin.reflect.full.memberProperties * INSTRUMENTATION_STATUS: stream=. * INSTRUMENTATION_STATUS: test=ignoreTest */ -class TestAnnotationProducer : RunListener() { +public class TestAnnotationProducer : RunListener() { override fun testStarted(description: Description?) { super.testStarted(description) if (description?.isTest == true) { diff --git a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/UnsafeAdbAccess.kt b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/UnsafeAdbAccess.kt index 3c538430a..3158b13bc 100644 --- a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/UnsafeAdbAccess.kt +++ b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/UnsafeAdbAccess.kt @@ -7,4 +7,4 @@ package com.malinskiy.adam.junit4.android "Its usage should be marked with '@com.malinskiy.adam.junit4.android.UnsafeAdbAccess' or '@OptIn(com.malinskiy.adam.junit4.android.UnsafeAdbAccess::class)' " + "if you accept the potential risks" ) -annotation class UnsafeAdbAccess +public annotation class UnsafeAdbAccess diff --git a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/AdbRule.kt b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/AdbRule.kt index 58013fcc1..2c4a8bcf9 100644 --- a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/AdbRule.kt +++ b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/AdbRule.kt @@ -35,12 +35,12 @@ import kotlin.coroutines.CoroutineContext * @param coroutineContext it's your responsibility to cancel this context when needed */ @OptIn(UnsafeAdbAccess::class) -class AdbRule(private val mode: Mode = Mode.ASSERT, private val coroutineContext: CoroutineContext = Dispatchers.IO) : +public class AdbRule(private val mode: Mode = Mode.ASSERT, private val coroutineContext: CoroutineContext = Dispatchers.IO) : TestRule { - lateinit var adb: SingleTargetAndroidDebugBridgeClient + public lateinit var adb: SingleTargetAndroidDebugBridgeClient @UnsafeAdbAccess - lateinit var adbUnsafe: AndroidDebugBridgeClient + public lateinit var adbUnsafe: AndroidDebugBridgeClient override fun apply(base: Statement, description: Description): Statement { return object : Statement() { diff --git a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/EmulatorConsoleRule.kt b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/EmulatorConsoleRule.kt index c911428d2..f5cfa9385 100644 --- a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/EmulatorConsoleRule.kt +++ b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/EmulatorConsoleRule.kt @@ -32,7 +32,7 @@ import kotlin.coroutines.CoroutineContext /** * @param coroutineContext it's your responsibility to cancel this context when needed */ -class EmulatorConsoleRule(private val mode: Mode = Mode.ASSERT, private val coroutineContext: CoroutineContext = Dispatchers.IO) : +public class EmulatorConsoleRule(private val mode: Mode = Mode.ASSERT, private val coroutineContext: CoroutineContext = Dispatchers.IO) : TestRule { private lateinit var client: AndroidDebugBridgeClient private lateinit var inetSocketAddress: InetSocketAddress @@ -68,5 +68,5 @@ class EmulatorConsoleRule(private val mode: Mode = Mode.ASSERT, private val coro } } - suspend fun execute(cmd: String) = client.execute(EmulatorCommandRequest(cmd, inetSocketAddress, authToken)) + public suspend fun execute(cmd: String): String = client.execute(EmulatorCommandRequest(cmd, inetSocketAddress, authToken)) } diff --git a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/EmulatorGrpcRule.kt b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/EmulatorGrpcRule.kt index 8e0bfe9fd..940c31d0f 100644 --- a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/EmulatorGrpcRule.kt +++ b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/EmulatorGrpcRule.kt @@ -31,11 +31,11 @@ import org.junit.runner.Description import org.junit.runners.model.Statement import java.util.concurrent.TimeUnit -class EmulatorGrpcRule( - val mode: Mode = Mode.ASSERT, +public class EmulatorGrpcRule( + public val mode: Mode = Mode.ASSERT, private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO ) : TestRule { - lateinit var grpc: EmulatorControllerGrpcKt.EmulatorControllerCoroutineStub + public lateinit var grpc: EmulatorControllerGrpcKt.EmulatorControllerCoroutineStub private var channel: ManagedChannel? = null override fun apply(base: Statement, description: Description): Statement { diff --git a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/Mode.kt b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/Mode.kt index 9db8056ac..87691cfae 100644 --- a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/Mode.kt +++ b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/Mode.kt @@ -16,7 +16,7 @@ package com.malinskiy.adam.junit4.android.rule -enum class Mode { +public enum class Mode { /** * Do not execute test if the rule can't be satisfied */ diff --git a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/sandbox/SingleTargetAndroidDebugBridgeClient.kt b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/sandbox/SingleTargetAndroidDebugBridgeClient.kt index 4ee5dc422..ed49ee242 100644 --- a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/sandbox/SingleTargetAndroidDebugBridgeClient.kt +++ b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/sandbox/SingleTargetAndroidDebugBridgeClient.kt @@ -23,12 +23,12 @@ import com.malinskiy.adam.request.MultiRequest import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.ReceiveChannel -class SingleTargetAndroidDebugBridgeClient(private val client: AndroidDebugBridgeClient, private val serial: String) { +public class SingleTargetAndroidDebugBridgeClient(private val client: AndroidDebugBridgeClient, private val serial: String) { - suspend fun execute(request: ComplexRequest): T = client.execute(request, serial) + public suspend fun execute(request: ComplexRequest): T = client.execute(request, serial) - fun execute(request: AsyncChannelRequest, scope: CoroutineScope): ReceiveChannel = + public fun execute(request: AsyncChannelRequest, scope: CoroutineScope): ReceiveChannel = client.execute(request, scope, serial) - suspend fun execute(request: MultiRequest): T = client.execute(request, serial) + public suspend fun execute(request: MultiRequest): T = client.execute(request, serial) } diff --git a/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureProcessor.kt b/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureProcessor.kt index 33f9d857e..b857f8928 100644 --- a/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureProcessor.kt +++ b/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureProcessor.kt @@ -44,7 +44,7 @@ import java.io.File * INSTRUMENTATION_STATUS: stream=. * INSTRUMENTATION_STATUS: test=ignoreTest */ -class AdamScreenCaptureProcessor : BasicScreenCaptureProcessor() { +public class AdamScreenCaptureProcessor : BasicScreenCaptureProcessor() { override fun process(capture: ScreenCapture): String? { val filename = super.process(capture) val absoluteScreenCapturePath = File(mDefaultScreenshotPath, filename) diff --git a/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureRule.kt b/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureRule.kt index b09ba5ef8..5e7ab15b2 100644 --- a/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureRule.kt +++ b/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureRule.kt @@ -26,7 +26,7 @@ import org.junit.runners.model.Statement /** * JUnit4 rule that produces test events with screenshot paths */ -class AdamScreenCaptureRule : TestRule { +public class AdamScreenCaptureRule : TestRule { override fun apply(base: Statement, description: Description): Statement { return object : Statement() { override fun evaluate() { diff --git a/buildSrc/src/main/kotlin/adam.android.library.gradle.kts b/buildSrc/src/main/kotlin/adam.android.library.gradle.kts index e30ed2941..3b0dccef2 100644 --- a/buildSrc/src/main/kotlin/adam.android.library.gradle.kts +++ b/buildSrc/src/main/kotlin/adam.android.library.gradle.kts @@ -7,6 +7,10 @@ plugins { // id("adam.code.lint") } +kotlin { + explicitApi() +} + android { defaultConfig { lint.targetSdk = ProjectConfig.TARGET_SDK From 77f12e5aa2a64e0a3af5e27f879f7ca06571d9f0 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sat, 14 Feb 2026 17:23:56 +0000 Subject: [PATCH 11/50] chore: update source and target compatibility to use ProjectConfig --- android-testrunner-contract/build.gradle.kts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/android-testrunner-contract/build.gradle.kts b/android-testrunner-contract/build.gradle.kts index 0ad0e7dae..ceb613739 100644 --- a/android-testrunner-contract/build.gradle.kts +++ b/android-testrunner-contract/build.gradle.kts @@ -1,3 +1,5 @@ +import adam.buildlogic.ProjectConfig + /* * Copyright (C) 2021 Anton Malinskiy * @@ -19,13 +21,13 @@ plugins { } java { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = ProjectConfig.JavaVersion + targetCompatibility = ProjectConfig.JavaVersion } tasks.withType{ compilerOptions { - jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11) + jvmTarget.set(ProjectConfig.JvmTarget) } } From 688de77704aa7cbfe36e6f33aadf0324cb2fc81d Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sat, 14 Feb 2026 17:35:27 +0000 Subject: [PATCH 12/50] chore: apply spotless --- .../com/malinskiy/adam/extension/File.kt | 2 +- .../malinskiy/adam/extension/FileExtension.kt | 4 +- .../malinskiy/adam/integration/ApkE2ETest.kt | 21 +++--- .../com/malinskiy/adam/integration/E2ETest.kt | 29 ++++---- .../adam/integration/EmulatorE2ETest.kt | 4 +- .../malinskiy/adam/integration/FileE2ETest.kt | 41 +++++++---- .../adam/integration/LogcatE2ETest.kt | 21 ++++-- .../malinskiy/adam/integration/ManualTest.kt | 2 +- .../adam/integration/PortForwardE2ETest.kt | 38 +++++----- .../malinskiy/adam/integration/PullE2ETest.kt | 1 - .../adam/integration/ShellV2E2ETest.kt | 11 ++- .../adam/integration/TestRunnerE2ETest.kt | 47 ++++++++----- .../adam/integration/feature/AbbE2ETest.kt | 5 +- .../integration/feature/AbbExecE2ETest.kt | 18 ++--- .../adam/integration/feature/CmdE2ETest.kt | 38 +++++----- .../adam/integration/feature/LsV2E2ETest.kt | 8 ++- .../integration/feature/SendRecvV2E2ETest.kt | 35 +++++++--- .../adam/integration/feature/StatV2E2ETest.kt | 9 ++- .../com/malinskiy/adam/rule/AdbDeviceRule.kt | 12 ++-- .../com/malinskiy/adam/rule/DeviceType.kt | 4 +- .../adam/AndroidDebugBridgeClient.kt | 26 ++++--- .../adam/AndroidDebugBridgeClientFactory.kt | 4 +- .../main/kotlin/com/malinskiy/adam/Const.kt | 48 ++++++++----- .../adam/exception/PullFailedException.kt | 2 +- .../adam/exception/PushFailedException.kt | 2 +- .../exception/RequestValidationException.kt | 2 +- .../UnsupportedForwardingSpecException.kt | 4 +- .../UnsupportedImageProtocolException.kt | 2 +- .../com/malinskiy/adam/extension/ByteArray.kt | 20 +++--- .../com/malinskiy/adam/extension/Int.kt | 4 +- .../com/malinskiy/adam/extension/Socket.kt | 21 ++++-- .../adam/interactor/AdbBinaryInteractor.kt | 2 +- .../interactor/DiscoverAdbSocketInteractor.kt | 2 +- .../adam/interactor/StartAdbInteractor.kt | 4 +- .../adam/interactor/StopAdbInteractor.kt | 4 +- .../com/malinskiy/adam/io/AsyncFileReader.kt | 3 +- .../com/malinskiy/adam/io/AsyncFileWriter.kt | 2 +- .../com/malinskiy/adam/log/AdamLogging.kt | 4 +- .../adam/request/AsyncChannelRequest.kt | 2 +- .../malinskiy/adam/request/ComplexRequest.kt | 2 +- .../com/malinskiy/adam/request/Feature.kt | 4 +- .../com/malinskiy/adam/request/Request.kt | 4 +- .../adam/request/SynchronousRequest.kt | 7 +- .../adam/request/abb/AbbExecRequest.kt | 5 +- .../adam/request/adbd/RestartAdbdRequest.kt | 6 +- .../device/AsyncDeviceMonitorRequest.kt | 9 ++- .../adam/request/device/ListDevicesRequest.kt | 5 +- .../request/emu/EmulatorCommandRequest.kt | 4 +- .../adam/request/file/ListFilesRequest.kt | 25 +++---- .../forwarding/ListPortForwardsRequest.kt | 7 +- .../request/forwarding/PortForwardRequest.kt | 4 +- .../request/forwarding/PortForwardingRule.kt | 4 +- .../RemoveAllPortForwardsRequest.kt | 2 +- .../forwarding/RemovePortForwardRequest.kt | 2 +- .../BufferedImageScreenCaptureAdapter.kt | 27 +++++-- .../request/framebuffer/ColorModelFactory.kt | 11 +-- .../adam/request/framebuffer/ColorSpace.kt | 3 +- .../adam/request/framebuffer/RawImage.kt | 15 ++-- .../RawImageScreenCaptureAdapter.kt | 8 ++- .../framebuffer/ScreenCaptureAdapter.kt | 4 +- .../framebuffer/ScreenCaptureRequest.kt | 21 ++++-- .../adam/request/logcat/SyncLogcatRequest.kt | 22 +++--- .../request/mdns/ListMdnsServicesRequest.kt | 3 +- .../adam/request/mdns/MdnsService.kt | 2 +- .../malinskiy/adam/request/mdns/MdnsStatus.kt | 2 +- .../adam/request/misc/ConnectDeviceRequest.kt | 2 +- .../request/misc/DisconnectDeviceRequest.kt | 4 +- .../adam/request/misc/ExecInRequest.kt | 15 ++-- .../adam/request/misc/PairDeviceRequest.kt | 4 +- .../adam/request/misc/RebootRequest.kt | 2 +- .../adam/request/misc/ReconnectRequest.kt | 4 +- .../request/misc/RemountPartitionsRequest.kt | 10 ++- .../pkg/AtomicInstallPackageRequest.kt | 32 ++++++--- .../pkg/InstallRemotePackageRequest.kt | 9 ++- .../request/pkg/InstallSplitPackageRequest.kt | 17 +++-- .../adam/request/pkg/LegacySideloadRequest.kt | 2 +- .../adam/request/pkg/PmListRequest.kt | 6 +- .../adam/request/pkg/SideloadRequest.kt | 6 +- .../pkg/StreamingPackageInstallRequest.kt | 4 +- .../pkg/UninstallRemotePackageRequest.kt | 4 +- .../request/pkg/multi/AddSessionRequest.kt | 6 +- .../CreateIndividualPackageSessionRequest.kt | 8 ++- .../multi/CreateMultiPackageSessionRequest.kt | 4 +- .../request/pkg/multi/InstallCommitRequest.kt | 12 ++-- .../multi/WriteIndividualPackageRequest.kt | 8 ++- .../reverse/ListReversePortForwardsRequest.kt | 7 +- .../RemoveAllReversePortForwardsRequest.kt | 2 +- .../RemoveReversePortForwardRequest.kt | 4 +- .../reverse/ReversePortForwardRequest.kt | 2 +- .../reverse/ReversePortForwardingRule.kt | 4 +- .../security/SetDmVerityCheckingRequest.kt | 10 ++- .../shell/AsyncCompatShellCommandRequest.kt | 10 ++- .../shell/v1/ChanneledShellCommandRequest.kt | 2 +- .../request/shell/v1/ShellCommandResult.kt | 2 +- .../v1/ShellResultResponseTransformer.kt | 5 +- .../shell/v1/SyncShellCommandRequest.kt | 8 ++- .../shell/v2/ChanneledShellCommandRequest.kt | 20 ++++-- .../adam/request/shell/v2/MessageType.kt | 6 +- .../request/shell/v2/ShellCommandRequest.kt | 2 +- .../request/shell/v2/ShellCommandResult.kt | 2 +- .../shell/v2/SyncShellCommandRequest.kt | 10 ++- .../malinskiy/adam/request/sync/BFFSearch.kt | 10 ++- .../adam/request/sync/PullRequest.kt | 38 +++++----- .../adam/request/sync/PushRequest.kt | 47 ++++++++----- .../request/sync/base/BasePullFileRequest.kt | 12 ++-- .../request/sync/base/BasePushFileRequest.kt | 10 ++- .../sync/compat/CompatListFileRequest.kt | 5 +- .../sync/compat/CompatPullFileRequest.kt | 12 ++-- .../sync/compat/CompatPushFileRequest.kt | 12 ++-- .../sync/compat/CompatStatFileRequest.kt | 5 +- .../adam/request/sync/model/FileEntry.kt | 4 +- .../adam/request/sync/model/SyncFile.kt | 2 +- .../adam/request/sync/v1/ListFileRequest.kt | 9 +-- .../adam/request/sync/v1/PullFileRequest.kt | 2 +- .../adam/request/sync/v1/PushFileRequest.kt | 2 +- .../adam/request/sync/v1/StatFileRequest.kt | 5 +- .../adam/request/sync/v2/CompressionType.kt | 3 +- .../adam/request/sync/v2/ListFileRequest.kt | 8 ++- .../adam/request/sync/v2/PullFileRequest.kt | 2 +- .../adam/request/sync/v2/PushFileRequest.kt | 2 +- .../adam/request/sync/v2/StatFileRequest.kt | 5 +- .../request/testrunner/InstrumentOptions.kt | 2 +- .../testrunner/InstrumentationSizeOption.kt | 4 +- .../adam/request/testrunner/TestEvent.kt | 5 +- .../adam/request/testrunner/TestIdentifier.kt | 2 +- .../request/testrunner/TestRunnerRequest.kt | 2 +- .../testrunner/model/SessionResultCode.kt | 2 +- .../adam/request/testrunner/model/Status.kt | 3 +- .../request/testrunner/model/StatusKey.kt | 3 +- .../testrunner/model/TestStatusAggregator.kt | 2 +- .../request/testrunner/model/TokenType.kt | 2 +- .../InstrumentationResponseTransformer.kt | 28 ++++++-- .../transform/DumpResponseTransformer.kt | 2 +- .../transform/StringResponseTransformer.kt | 2 +- .../malinskiy/adam/transport/BufferFactory.kt | 9 ++- .../malinskiy/adam/transport/SocketFactory.kt | 6 +- .../adam/transport/SuspendCloseable.kt | 2 +- .../adam/transport/TransportResponse.kt | 4 +- .../adam/transport/vertx/VertxSocket.kt | 12 ++-- .../transport/vertx/VertxSocketFactory.kt | 20 ++++-- .../adam/AndroidDebugBridgeClientTest.kt | 21 +++--- .../adam/extension/ByteArrayExtensions.kt | 2 +- .../integration/AdbBinaryIntegrationTest.kt | 3 +- .../DiscoverAdbSocketInteractorTest.kt | 2 +- .../request/AsyncShellCommandRequestTest.kt | 2 +- .../com/malinskiy/adam/request/TargetTest.kt | 3 +- .../adam/request/abb/AbbExecRequestTest.kt | 6 +- .../device/FetchDeviceFeaturesRequestTest.kt | 8 +-- .../request/device/ListDevicesRequestTest.kt | 4 +- .../forwarding/ListPortForwardsRequestTest.kt | 12 ++-- .../request/forwarding/LocalPortSpecTest.kt | 3 +- .../forwarding/PortForwardRequestTest.kt | 2 +- .../request/forwarding/RemotePortSpecTest.kt | 2 +- .../RemovePortForwardRequestTest.kt | 8 ++- .../framebuffer/ScreenCaptureRequestTest.kt | 5 +- .../BufferedImageScreenCaptureAdapterTest.kt | 2 +- .../request/logcat/AsyncLogcatRequestTest.kt | 10 +-- .../mdns/ListMdnsServicesRequestTest.kt | 8 ++- .../adam/request/mdns/MdnsCheckRequestTest.kt | 1 - .../misc/DisconnectDeviceRequestTest.kt | 1 - .../misc/FetchHostFeaturesRequestTest.kt | 2 +- .../adam/request/misc/RebootRequestTest.kt | 4 +- .../pkg/InstallRemotePackageRequestTest.kt | 12 +++- .../pkg/multi/AddSessionRequestTest.kt | 16 +++-- ...eateIndividualPackageSessionRequestTest.kt | 10 +-- .../CreateMultiPackageSessionRequestTest.kt | 40 ++++++----- .../pkg/multi/InstallCommitRequestTest.kt | 10 +-- .../WriteIndividualPackageRequestTest.kt | 14 ++-- .../ListReversePortForwardsRequestTest.kt | 22 ++++-- .../RemoveReversePortForwardRequestTest.kt | 4 +- .../reverse/ReversePortForwardRequestTest.kt | 7 +- .../v1/ChanneledShellCommandRequestTest.kt | 6 +- .../shell/v1/ShellCommandRequestTest.kt | 1 - .../v1/ShellResultResponseTransformerTest.kt | 2 +- .../v2/ChanneledShellCommandRequestTest.kt | 2 +- .../shell/v2/ShellCommandRequestTest.kt | 1 - .../adam/request/sync/ListFilesRequestTest.kt | 18 ++--- .../sync/compat/CompatListFileRequestTest.kt | 18 ++--- .../sync/compat/CompatStatFileRequestTest.kt | 11 +-- .../request/sync/v1/ListFileRequestTest.kt | 10 +-- .../request/sync/v1/PullFileRequestTest.kt | 8 ++- .../request/sync/v1/PushFileRequestTest.kt | 1 - .../request/sync/v1/StatFileRequestTest.kt | 1 - .../request/sync/v2/ListFileRequestTest.kt | 9 +-- .../request/sync/v2/PullFileRequestTest.kt | 19 +++-- .../request/sync/v2/PushFileRequestTest.kt | 1 - .../request/sync/v2/StatFileRequestTest.kt | 13 ++-- .../testrunner/InstrumentOptionsTest.kt | 30 ++++---- .../testrunner/TestRunnerRequestTest.kt | 70 +++++++++++-------- .../InstrumentationResponseTransformerTest.kt | 3 +- .../build.gradle.kts | 2 +- .../listener/TestAnnotationProducer.kt | 7 +- android-junit4/build.gradle.kts | 1 - .../adam/junit4/android/UnsafeAdbAccess.kt | 8 ++- .../adam/junit4/android/rule/AdbRule.kt | 11 ++- .../android/rule/EmulatorConsoleRule.kt | 19 +++-- .../junit4/android/rule/EmulatorGrpcRule.kt | 12 +++- .../adam/junit4/android/rule/Mode.kt | 2 +- .../SingleTargetAndroidDebugBridgeClient.kt | 11 ++- .../AdamScreenCaptureProcessor.kt | 2 +- .../adam/transport/ktor/KtorSocketFactory.kt | 5 +- 201 files changed, 1118 insertions(+), 710 deletions(-) diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/extension/File.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/extension/File.kt index 12bb0c107..f7bb34d7a 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/extension/File.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/extension/File.kt @@ -25,4 +25,4 @@ fun File.md5(): String { return digested.joinToString("") { String.format("%02x", it) } -} \ No newline at end of file +} diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/extension/FileExtension.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/extension/FileExtension.kt index 8ac0816c1..4e38df5f9 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/extension/FileExtension.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/extension/FileExtension.kt @@ -21,7 +21,9 @@ import kotlinx.coroutines.channels.ReceiveChannel import kotlinx.coroutines.channels.produce import java.io.File -fun CoroutineScope.sequentialRead(file: File, sizeChannel: ReceiveChannel): ReceiveChannel = produce(capacity = 1) { +fun CoroutineScope.sequentialRead(file: File, sizeChannel: ReceiveChannel): ReceiveChannel = produce( + capacity = 1, +) { file.inputStream().buffered().use { stream -> var position = 0 for (size in sizeChannel) { diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/ApkE2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/ApkE2ETest.kt index 008d74f95..36ea47e42 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/ApkE2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/ApkE2ETest.kt @@ -75,14 +75,17 @@ class ApkE2ETest { client.execute( PushFileRequest(testFile, "/data/local/tmp/$fileName", coroutineContext = coroutineContext), this, - serial = adb.deviceSerial + serial = adb.deviceSerial, ) for (result in channel) { - //Do something with result + // Do something with result } - client.execute(InstallRemotePackageRequest("/data/local/tmp/$fileName", true), serial = adb.deviceSerial).let { + client.execute( + InstallRemotePackageRequest("/data/local/tmp/$fileName", true), + serial = adb.deviceSerial, + ).let { println(it) } }.let { println(it) } @@ -108,12 +111,12 @@ class ApkE2ETest { InstallSplitPackageRequest( ApkSplitInstallationPackage(appFile1, appFile2), listOf(), - true + true, ), - adb.deviceSerial + adb.deviceSerial, ) - //Takes some time until it shows in the pm list. Wait for 10 seconds max + // Takes some time until it shows in the pm list. Wait for 10 seconds max var packages: List = emptyList() for (i in 1..100) { packages = client.execute(PmListRequest(), serial = adb.deviceSerial) @@ -138,12 +141,12 @@ class ApkE2ETest { ApkSplitInstallationPackage(appFile1, appFile2), listOf(), true, - extraArgs = listOf("-t") + extraArgs = listOf("-t"), ), - adb.deviceSerial + adb.deviceSerial, ) - //Takes some time until it shows in the pm list. Wait for 10 seconds max + // Takes some time until it shows in the pm list. Wait for 10 seconds max var packages: List = emptyList() for (i in 1..100) { packages = client.execute(PmListRequest(), serial = adb.deviceSerial) diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/E2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/E2ETest.kt index bba9cd1f7..2d7d578e5 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/E2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/E2ETest.kt @@ -44,7 +44,6 @@ import java.io.File import java.io.IOException import javax.imageio.ImageIO - class E2ETest { @Rule @JvmField @@ -55,7 +54,7 @@ class E2ETest { runBlocking { val image = adbRule.adb.execute( ScreenCaptureRequest(RawImageScreenCaptureAdapter()), - adbRule.deviceSerial + adbRule.deviceSerial, ).toBufferedImage() if (!ImageIO.write(image, "png", File("/tmp/screen.png"))) { @@ -75,13 +74,13 @@ class E2ETest { runBlocking { val response = adbRule.adb.execute( ShellCommandRequest("echo hello"), - adbRule.deviceSerial + adbRule.deviceSerial, ) assertThat(response).isEqualTo( ShellCommandResult( "hello${adbRule.lineSeparator}".toByteArray(Const.DEFAULT_TRANSPORT_ENCODING), - 0 - ) + 0, + ), ) } } @@ -91,7 +90,7 @@ class E2ETest { runBlocking { val response = adbRule.adb.execute( ShellCommandRequest("false"), - adbRule.deviceSerial + adbRule.deviceSerial, ) assertThat(response.exitCode).isNotEqualTo(0) } @@ -102,7 +101,7 @@ class E2ETest { runBlocking { val response = adbRule.adb.execute( ShellCommandRequest("echo -n 1"), - adbRule.deviceSerial + adbRule.deviceSerial, ) assertThat(response.exitCode).isEqualTo(0) assertThat(response.output).isEqualTo("1") @@ -114,12 +113,12 @@ class E2ETest { runBlocking { val lineSeparator = adbRule.adb.execute( ShellCommandRequest("echo"), - adbRule.deviceSerial + adbRule.deviceSerial, ).output val response = adbRule.adb.execute( ShellCommandRequest("uname"), - adbRule.deviceSerial + adbRule.deviceSerial, ) assertThat(response.output).endsWith(lineSeparator) } @@ -130,7 +129,7 @@ class E2ETest { runBlocking { val props = adbRule.adb.execute( GetPropRequest(), - adbRule.deviceSerial + adbRule.deviceSerial, ) assertThat(props["sys.boot_completed"]).isEqualTo("1") } @@ -141,7 +140,7 @@ class E2ETest { runBlocking { val response = adbRule.adb.execute( GetSinglePropRequest("sys.boot_completed"), - adbRule.deviceSerial + adbRule.deviceSerial, ) assertThat(response).isEqualTo("1${adbRule.lineSeparator}") } @@ -153,7 +152,7 @@ class E2ETest { val channel = adbRule.adb.execute( serial = adbRule.deviceSerial, request = ChanneledLogcatRequest(), - scope = this + scope = this, ) val line = channel.receive() @@ -167,7 +166,7 @@ class E2ETest { runBlocking { val list = adbRule.adb.execute( ListDevicesRequest(), - adbRule.deviceSerial + adbRule.deviceSerial, ) assertThat(list).hasSize(1) @@ -195,12 +194,12 @@ class E2ETest { @Test fun testFetchDeviceFeatures() = runBlocking { val features = adbRule.adb.execute(FetchDeviceFeaturesRequest(adbRule.deviceSerial)) - //No exception means it's working, but every emulator has a different feature set + // No exception means it's working, but every emulator has a different feature set } @Test fun testFetchHostFeatures() = runBlocking { adbRule.adb.execute(FetchHostFeaturesRequest()).let { println(it) } - //No exception means it's working + // No exception means it's working } } diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/EmulatorE2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/EmulatorE2ETest.kt index 7385b311b..bef01c720 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/EmulatorE2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/EmulatorE2ETest.kt @@ -39,8 +39,8 @@ class EmulatorE2ETest { val output = adbRule.adb.execute( EmulatorCommandRequest( "help", - InetSocketAddress("localhost", port) - ) + InetSocketAddress("localhost", port), + ), ) assertThat(output).startsWith("Android console commands") } diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/FileE2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/FileE2ETest.kt index 7d40830ba..bb6da1a4b 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/FileE2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/FileE2ETest.kt @@ -90,21 +90,28 @@ class FileE2ETest { val fileName = testFile.name runBlocking { val channel = - adbRule.adb.execute(PushFileRequest(testFile, "/data/local/tmp/$fileName"), this, serial = adbRule.deviceSerial) + adbRule.adb.execute( + PushFileRequest(testFile, "/data/local/tmp/$fileName"), + this, + serial = adbRule.deviceSerial, + ) var percentage = 0 - for(percentageDouble in channel) { + for (percentageDouble in channel) { val newPercentage = (percentageDouble * 100).roundToInt() if (newPercentage != percentage) { print('.') percentage = newPercentage } } - + val stats = adbRule.adb.execute(StatFileRequest("/data/local/tmp/app-debug.apk"), adbRule.deviceSerial) assertThat(stats.size).isEqualTo(testFile.length().toUInt()) - val sizeString = adbRule.adb.execute(ShellCommandRequest("${md5()} /data/local/tmp/app-debug.apk"), adbRule.deviceSerial) + val sizeString = adbRule.adb.execute( + ShellCommandRequest("${md5()} /data/local/tmp/app-debug.apk"), + adbRule.deviceSerial, + ) val split = sizeString.output.split(" ").filter { it != "" } /** @@ -113,7 +120,7 @@ class FileE2ETest { */ assertThat(split[0]).isEqualTo(testFile.md5()) - //TODO figure out why 644 is actually pushed as 666 + // TODO figure out why 644 is actually pushed as 666 assertThat(stats.mode).isEqualTo("100777".toUInt(radix = 8)) } } @@ -134,9 +141,16 @@ class FileE2ETest { withTimeout(10_000) { while (true) { var output = - adbRule.adb.execute(ShellCommandRequest("echo cafebabe > /data/local/tmp/testfile"), serial = adbRule.deviceSerial) + adbRule.adb.execute( + ShellCommandRequest("echo cafebabe > /data/local/tmp/testfile"), + serial = adbRule.deviceSerial, + ) println(output) - output = adbRule.adb.execute(ShellCommandRequest("cat /data/local/tmp/testfile"), serial = adbRule.deviceSerial) + output = + adbRule.adb.execute( + ShellCommandRequest("cat /data/local/tmp/testfile"), + serial = adbRule.deviceSerial, + ) println(output) if (output.output.contains("cafebabe") && output.exitCode == 0) { break @@ -148,11 +162,11 @@ class FileE2ETest { val channel = adbRule.adb.execute( PullFileRequest("/data/local/tmp/testfile", testFile, coroutineContext = coroutineContext), this, - adbRule.deviceSerial + adbRule.deviceSerial, ) var percentage = 0 - for(percentageDouble in channel) { + for (percentageDouble in channel) { val newPercentage = (percentageDouble * 100).roundToInt() if (newPercentage != percentage) { print('.') @@ -162,7 +176,10 @@ class FileE2ETest { println() }.join() - val sizeString = adbRule.adb.execute(ShellCommandRequest("ls -ln /data/local/tmp/testfile"), adbRule.deviceSerial) + val sizeString = adbRule.adb.execute( + ShellCommandRequest("ls -ln /data/local/tmp/testfile"), + adbRule.deviceSerial, + ) val split = sizeString.output.split(" ").filter { it != "" } /** @@ -187,11 +204,11 @@ class FileE2ETest { val channel = adbRule.adb.execute( PullFileRequest("/data/local/tmp/shoudnotexist", testFile, coroutineContext = coroutineContext), this, - adbRule.deviceSerial + adbRule.deviceSerial, ) var percentage = 0 - for(percentageDouble in channel) { + for (percentageDouble in channel) { val newPercentage = (percentageDouble * 100).roundToInt() if (newPercentage != percentage) { print('.') diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/LogcatE2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/LogcatE2ETest.kt index 3d0260c22..919deadc0 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/LogcatE2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/LogcatE2ETest.kt @@ -44,7 +44,7 @@ import java.util.regex.Pattern private val BUFFER_BEGIN_RE = Pattern.compile("--------- beginning of (.*)") private val LOG_LINE_RE = Pattern.compile( "((?:(\\d\\d\\d\\d)-)?(\\d\\d)-(\\d\\d)\\s+(\\d\\d):(\\d\\d):(\\d\\d)\\.(\\d\\d\\d)\\s+(\\d+)\\s+(\\d+)\\s+(.)\\s+)(.*?):\\s(.*)", - Pattern.MULTILINE + Pattern.MULTILINE, ) private val sinceFormatter = DateTimeFormatter.ofPattern("MM-dd HH:mm:ss.SSS") .withZone(ZoneId.systemDefault()) @@ -66,10 +66,11 @@ class LogcatE2ETest { val deviceTimezone = TimeZone.getTimeZone(deviceTimezoneString) val nowInstant = Instant.now() - val request = SyncLogcatRequest(LogcatSinceFormat.DateString(nowInstant, deviceTimezoneString), modes = listOf()) + val request = + SyncLogcatRequest(LogcatSinceFormat.DateString(nowInstant, deviceTimezoneString), modes = listOf()) async { delay(100) - //Produce artificial message in logcat + // Produce artificial message in logcat adb.adb.execute(ShellCommandRequest("log -t TEST_TAG \"Test message\""), adb.deviceSerial) } @@ -88,11 +89,15 @@ class LogcatE2ETest { @Test fun testChanneledRequest() { runBlocking { - val deviceTimezoneString = adb.adb.execute(GetSinglePropRequest("persist.sys.timezone"), adb.deviceSerial).trim() + val deviceTimezoneString = adb.adb.execute( + GetSinglePropRequest("persist.sys.timezone"), + adb.deviceSerial, + ).trim() val deviceTimezone = TimeZone.getTimeZone(deviceTimezoneString) val nowInstant = Instant.now() - val request = ChanneledLogcatRequest(LogcatSinceFormat.DateString(nowInstant, deviceTimezoneString), modes = listOf()) + val request = + ChanneledLogcatRequest(LogcatSinceFormat.DateString(nowInstant, deviceTimezoneString), modes = listOf()) val content = mutableSetOf() val channel = adb.adb.execute(request, this, adb.deviceSerial) @@ -100,7 +105,7 @@ class LogcatE2ETest { val background: Deferred = async { while (isActive) { delay(100) - //Produce artificial message in logcat + // Produce artificial message in logcat adb.adb.execute(ShellCommandRequest("log -t TEST_TAG \"Test message\""), adb.deviceSerial) } } @@ -148,7 +153,9 @@ class LogcatE2ETest { val instant get() = ZonedDateTime.ofInstant(date.toInstant(), timeZone.toZoneId()) - override fun toString() = "[LogLine] ${sinceFormatter.format(date.toInstant())} $pid $tid $level $tag: $text" + override fun toString() = "[LogLine] ${sinceFormatter.format( + date.toInstant(), + )} $pid $tid $level $tag: $text" override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/ManualTest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/ManualTest.kt index db8deb88f..771d4debe 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/ManualTest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/ManualTest.kt @@ -37,7 +37,7 @@ class ManualTest { runBlocking { val execute = adbRule.adb.execute( request = AsyncDeviceMonitorRequest(), - scope = this + scope = this, ) for (i in 1..100) { println(execute.receive()) diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PortForwardE2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PortForwardE2ETest.kt index 41ed8eb2f..1975d9672 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PortForwardE2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PortForwardE2ETest.kt @@ -67,12 +67,12 @@ class PortForwardE2ETest { runBlocking { adbRule.adb.execute( PortForwardRequest(LocalTcpPortSpec(12042), RemoteTcpPortSpec(12042), serial = adbRule.deviceSerial), - adbRule.deviceSerial + adbRule.deviceSerial, ) val portForwards = adbRule.adb.execute( ListPortForwardsRequest(adbRule.deviceSerial), - adbRule.deviceSerial + adbRule.deviceSerial, ) assertThat(portForwards).hasSize(1) @@ -84,10 +84,14 @@ class PortForwardE2ETest { assertThat(rule.remoteSpec).isInstanceOf(RemoteTcpPortSpec::class) assertThat((rule.remoteSpec as RemoteTcpPortSpec).port).isEqualTo(12042) - adbRule.adb.execute(RemovePortForwardRequest(LocalTcpPortSpec(12042), serial = adbRule.deviceSerial), adbRule.deviceSerial) + adbRule.adb.execute( + RemovePortForwardRequest(LocalTcpPortSpec(12042), serial = adbRule.deviceSerial), + adbRule.deviceSerial, + ) val afterAllForwards = adbRule.adb.execute( - ListPortForwardsRequest(adbRule.deviceSerial), adbRule.deviceSerial + ListPortForwardsRequest(adbRule.deviceSerial), + adbRule.deviceSerial, ) assertThat(afterAllForwards).isEmpty() @@ -99,11 +103,12 @@ class PortForwardE2ETest { runBlocking { val portString = adbRule.adb.execute( PortForwardRequest(LocalTcpPortSpec(), RemoteTcpPortSpec(12042), serial = adbRule.deviceSerial), - adbRule.deviceSerial + adbRule.deviceSerial, ) val currentPortForwards = adbRule.adb.execute( - ListPortForwardsRequest(adbRule.deviceSerial), adbRule.deviceSerial + ListPortForwardsRequest(adbRule.deviceSerial), + adbRule.deviceSerial, ) assertThat(portString).isNotNull() @@ -119,17 +124,17 @@ class PortForwardE2ETest { runBlocking { adbRule.adb.execute( PortForwardRequest(LocalTcpPortSpec(12042), RemoteTcpPortSpec(12042), serial = adbRule.deviceSerial), - adbRule.deviceSerial + adbRule.deviceSerial, ) adbRule.adb.execute( RemovePortForwardRequest(LocalTcpPortSpec(12042), serial = adbRule.deviceSerial), - adbRule.deviceSerial + adbRule.deviceSerial, ) val portForwards = adbRule.adb.execute( ListPortForwardsRequest(adbRule.deviceSerial), - adbRule.deviceSerial + adbRule.deviceSerial, ) assertThat(portForwards).isEmpty() @@ -144,18 +149,18 @@ class PortForwardE2ETest { adbRule.adb.execute( ReversePortForwardRequest(RemoteTcpPortSpec(12043), LocalTcpPortSpec(12043)), - adbRule.deviceSerial + adbRule.deviceSerial, ) val list = adbRule.adb.execute(ListReversePortForwardsRequest(), adbRule.deviceSerial) assertThat(list).hasSize(1) - //Host serial is of form "host-$tid", we ignore it here for equality check + // Host serial is of form "host-$tid", we ignore it here for equality check assertThat(list.first().localSpec).isEqualTo(RemoteTcpPortSpec(12043)) assertThat(list.first().remoteSpec).isEqualTo(LocalTcpPortSpec(12043)) adbRule.adb.execute( RemoveReversePortForwardRequest(RemoteTcpPortSpec(12043)), - adbRule.deviceSerial + adbRule.deviceSerial, ) assertThat(adbRule.adb.execute(ListReversePortForwardsRequest(), adbRule.deviceSerial)).isEmpty() @@ -166,21 +171,22 @@ class PortForwardE2ETest { runBlocking { val portString = adbRule.adb.execute( ReversePortForwardRequest(RemoteTcpPortSpec(12042), LocalTcpPortSpec(12042)), - adbRule.deviceSerial + adbRule.deviceSerial, ) val currentPortForwards = adbRule.adb.execute( - ListReversePortForwardsRequest(), adbRule.deviceSerial + ListReversePortForwardsRequest(), + adbRule.deviceSerial, ) if (portString != null) { - //Some devices return the allocated port + // Some devices return the allocated port val actual = portString val expected = (currentPortForwards.firstOrNull()?.localSpec as RemoteTcpPortSpec).port assertThat(actual).isEqualTo(expected) } else { - //Others do not + // Others do not val actual = currentPortForwards.any { it.remoteSpec == LocalTcpPortSpec(12042) && it.localSpec == RemoteTcpPortSpec(12042) } diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PullE2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PullE2ETest.kt index 36c91aaf3..bf45ecd75 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PullE2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PullE2ETest.kt @@ -183,4 +183,3 @@ class PullE2ETest { } } } - diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/ShellV2E2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/ShellV2E2ETest.kt index aaec4ffcd..86c198002 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/ShellV2E2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/ShellV2E2ETest.kt @@ -50,18 +50,18 @@ class ShellV2E2ETest { fun testChanneled() = runBlocking { val stdio = Channel() val receiveChannel = adbRule.adb.execute(ChanneledShellCommandRequest("cat", stdio), this, adbRule.deviceSerial) - //Sending commands requires additional pool, otherwise we might deadlock + // Sending commands requires additional pool, otherwise we might deadlock val stdioJob = launch(Dispatchers.IO) { stdio.send( ShellCommandInputChunk( - stdin = "cafebabe".toByteArray(Const.DEFAULT_TRANSPORT_ENCODING) - ) + stdin = "cafebabe".toByteArray(Const.DEFAULT_TRANSPORT_ENCODING), + ), ) stdio.send( ShellCommandInputChunk( - close = true - ) + close = true, + ), ) } @@ -78,6 +78,5 @@ class ShellV2E2ETest { assertThat(stdoutBuilder.toString()).isEqualTo("cafebabe") assertThat(stderrBuilder.toString()).isEmpty() assertThat(exitCode).isEqualTo(0) - } } diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/TestRunnerE2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/TestRunnerE2ETest.kt index 749260985..1bc09a174 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/TestRunnerE2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/TestRunnerE2ETest.kt @@ -77,10 +77,10 @@ class TestRunnerE2ETest { TestRunnerRequest( "com.example.test", InstrumentOptions( - clazz = listOf("com.example.AbstractFailingTest") + clazz = listOf("com.example.AbstractFailingTest"), ), rule.supportedFeatures, - this + this, ), serial = rule.deviceSerial, ) @@ -113,7 +113,7 @@ class TestRunnerE2ETest { TestRunnerRequest( "com.example.test", InstrumentOptions( - clazz = listOf("com.example.AbstractFailingTest") + clazz = listOf("com.example.AbstractFailingTest"), ), rule.supportedFeatures, this, @@ -128,19 +128,30 @@ class TestRunnerE2ETest { } assertThat(events).contains(TestRunStartedEvent(1)) - assertThat(events).contains(TestStarted(TestIdentifier("com.example.AbstractFailingTest", "testAlwaysFailing"))) - - assertThat(events.any { - it is TestFailed && it.id.className == "com.example.AbstractFailingTest" && it.id.testName == "testAlwaysFailing" && it.stackTrace.isNotEmpty() - }).isTrue() - - assertThat(events.any { - it is TestEnded && it.id.className == "com.example.AbstractFailingTest" && it.id.testName == "testAlwaysFailing" - }).isTrue() - - assertThat(events.any { - it is TestRunEnded && it.metrics.isEmpty() && it.elapsedTimeMillis > 0 - }) + assertThat( + events, + ).contains(TestStarted(TestIdentifier("com.example.AbstractFailingTest", "testAlwaysFailing"))) + + assertThat( + events.any { + it is TestFailed && it.id.className == "com.example.AbstractFailingTest" && + it.id.testName == "testAlwaysFailing" && + it.stackTrace.isNotEmpty() + }, + ).isTrue() + + assertThat( + events.any { + it is TestEnded && it.id.className == "com.example.AbstractFailingTest" && + it.id.testName == "testAlwaysFailing" + }, + ).isTrue() + + assertThat( + events.any { + it is TestRunEnded && it.metrics.isEmpty() && it.elapsedTimeMillis > 0 + }, + ) } } @@ -149,7 +160,7 @@ class TestRunnerE2ETest { rule.adb.execute( PushFileRequest(apk, "/data/local/tmp/$apkFileName", coroutineContext = coroutineContext), this, - serial = rule.deviceSerial + serial = rule.deviceSerial, ) for (i in channel) { @@ -158,7 +169,7 @@ class TestRunnerE2ETest { val result = rule.adb.execute( InstallRemotePackageRequest("/data/local/tmp/$apkFileName", true), - serial = rule.deviceSerial + serial = rule.deviceSerial, ) println(result) } diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/AbbE2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/AbbE2ETest.kt index b4ed6a503..6e905f1b4 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/AbbE2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/AbbE2ETest.kt @@ -34,7 +34,10 @@ class AbbE2ETest { @Test fun testStreamingInstallRequest() { runBlocking { - var result = adbRule.adb.execute(AbbRequest(listOf("-l"), adbRule.supportedFeatures), serial = adbRule.deviceSerial) + var result = adbRule.adb.execute( + AbbRequest(listOf("-l"), adbRule.supportedFeatures), + serial = adbRule.deviceSerial, + ) assertThat(result.output).startsWith("Currently running services:") } } diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/AbbExecE2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/AbbExecE2ETest.kt index 88634765d..8026b8afb 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/AbbExecE2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/AbbExecE2ETest.kt @@ -69,9 +69,9 @@ class AbbExecE2ETest { StreamingPackageInstallRequest( pkg = testFile, supportedFeatures = listOf(Feature.ABB_EXEC), - reinstall = false + reinstall = false, ), - adb.deviceSerial + adb.deviceSerial, ) }.let { println(it) } @@ -90,15 +90,15 @@ class AbbExecE2ETest { AtomicInstallPackageRequest( listOf( SingleFileInstallationPackage(appFile), - SingleFileInstallationPackage(testFile) + SingleFileInstallationPackage(testFile), ), listOf(Feature.ABB_EXEC), - true + true, ), - adb.deviceSerial + adb.deviceSerial, ) - //Takes some time until it shows in the pm list. Wait for 10 seconds max + // Takes some time until it shows in the pm list. Wait for 10 seconds max var packages: List = emptyList() for (i in 1..100) { packages = client.execute(PmListRequest(), serial = adb.deviceSerial) @@ -124,12 +124,12 @@ class AbbExecE2ETest { InstallSplitPackageRequest( ApkSplitInstallationPackage(appFile1, appFile2), listOf(Feature.ABB_EXEC), - true + true, ), - adb.deviceSerial + adb.deviceSerial, ) - //Takes some time until it shows in the pm list. Wait for 10 seconds max + // Takes some time until it shows in the pm list. Wait for 10 seconds max var packages: List = emptyList() for (i in 1..100) { packages = client.execute(PmListRequest(), serial = adb.deviceSerial) diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/CmdE2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/CmdE2ETest.kt index 3a4f87478..43ae73c3c 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/CmdE2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/CmdE2ETest.kt @@ -75,9 +75,9 @@ class CmdE2ETest { StreamingPackageInstallRequest( pkg = testFile, supportedFeatures = listOf(Feature.CMD), - reinstall = false + reinstall = false, ), - adb.deviceSerial + adb.deviceSerial, ) }.let { println(it) } @@ -99,7 +99,7 @@ class CmdE2ETest { reinstall = false, extraArgs = listOf("-g", "-r"), ), - adb.deviceSerial + adb.deviceSerial, ) }.let { println(it) } @@ -120,12 +120,12 @@ class CmdE2ETest { ExecInRequest( "cmd package install -S ${testFile.length()}", channel, - blockSizeChannel + blockSizeChannel, ), - adb.deviceSerial + adb.deviceSerial, ) - //Takes some time until it shows in the pm list. Wait for 10 seconds max + // Takes some time until it shows in the pm list. Wait for 10 seconds max var packages: List = emptyList() for (i in 1..100) { packages = client.execute(PmListRequest(), serial = adb.deviceSerial) @@ -150,24 +150,24 @@ class CmdE2ETest { AtomicInstallPackageRequest( listOf( SingleFileInstallationPackage(appFile), - SingleFileInstallationPackage(testFile) + SingleFileInstallationPackage(testFile), ), listOf(Feature.CMD), - true + true, ), - adb.deviceSerial + adb.deviceSerial, ) } catch (e: RequestRejectedException) { if (e.message?.contains("Unknown option --multi-package") == true) { Assume.assumeTrue( "Device doesn't support `--multi-package` option", - false + false, ) } throw e } - //Takes some time until it shows in the pm list. Wait for 10 seconds max + // Takes some time until it shows in the pm list. Wait for 10 seconds max var packages: List = emptyList() for (i in 1..100) { packages = client.execute(PmListRequest(), serial = adb.deviceSerial) @@ -194,25 +194,25 @@ class CmdE2ETest { AtomicInstallPackageRequest( listOf( SingleFileInstallationPackage(appFile), - SingleFileInstallationPackage(testFile) + SingleFileInstallationPackage(testFile), ), listOf(Feature.CMD), true, - extraArgs = listOf("-r", "-g") + extraArgs = listOf("-r", "-g"), ), - adb.deviceSerial + adb.deviceSerial, ) } catch (e: RequestRejectedException) { if (e.message?.contains("Unknown option --multi-package") == true) { Assume.assumeTrue( "Device doesn't support `--multi-package` option", - false + false, ) } throw e } - //Takes some time until it shows in the pm list. Wait for 10 seconds max + // Takes some time until it shows in the pm list. Wait for 10 seconds max var packages: List = emptyList() for (i in 1..100) { packages = client.execute(PmListRequest(), serial = adb.deviceSerial) @@ -238,12 +238,12 @@ class CmdE2ETest { InstallSplitPackageRequest( ApkSplitInstallationPackage(appFile1, appFile2), listOf(Feature.CMD), - true + true, ), - adb.deviceSerial + adb.deviceSerial, ) - //Takes some time until it shows in the pm list. Wait for 10 seconds max + // Takes some time until it shows in the pm list. Wait for 10 seconds max var packages: List = emptyList() for (i in 1..100) { packages = client.execute(PmListRequest(), serial = adb.deviceSerial) diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/LsV2E2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/LsV2E2ETest.kt index 746e3e54f..ec0a81dcf 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/LsV2E2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/LsV2E2ETest.kt @@ -36,14 +36,18 @@ class LsV2E2ETest { @Before fun setup() { runBlocking { - externalStorageMount = adbRule.adb.execute(ShellCommandRequest("echo \$EXTERNAL_STORAGE"), adbRule.deviceSerial).output.trim() + externalStorageMount = + adbRule.adb.execute(ShellCommandRequest("echo \$EXTERNAL_STORAGE"), adbRule.deviceSerial).output.trim() } } @Test fun testListFile() { runBlocking { - val list = adbRule.adb.execute(ListFileRequest(externalStorageMount, adbRule.supportedFeatures), adbRule.deviceSerial) + val list = adbRule.adb.execute( + ListFileRequest(externalStorageMount, adbRule.supportedFeatures), + adbRule.deviceSerial, + ) for (i in list) { println(i) } diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/SendRecvV2E2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/SendRecvV2E2ETest.kt index f11d104ee..c7a075a61 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/SendRecvV2E2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/SendRecvV2E2ETest.kt @@ -54,9 +54,16 @@ class SendRecvV2E2ETest { withTimeout(10_000) { while (true) { var output = - adbRule.adb.execute(ShellCommandRequest("echo cafebabe > /data/local/tmp/testfile"), serial = adbRule.deviceSerial) + adbRule.adb.execute( + ShellCommandRequest("echo cafebabe > /data/local/tmp/testfile"), + serial = adbRule.deviceSerial, + ) println(output) - output = adbRule.adb.execute(ShellCommandRequest("cat /data/local/tmp/testfile"), serial = adbRule.deviceSerial) + output = + adbRule.adb.execute( + ShellCommandRequest("cat /data/local/tmp/testfile"), + serial = adbRule.deviceSerial, + ) println(output) if (output.output.contains("cafebabe") && output.exitCode == 0) { break @@ -80,13 +87,18 @@ class SendRecvV2E2ETest { val file = temp.newFile() val channel = adbRule.adb.execute( - PullFileRequest("/data/local/tmp/testfile", file, adbRule.supportedFeatures, coroutineContext = coroutineContext), + PullFileRequest( + "/data/local/tmp/testfile", + file, + adbRule.supportedFeatures, + coroutineContext = coroutineContext, + ), this, - adbRule.deviceSerial + adbRule.deviceSerial, ) var percentage = 0 - for(percentageDouble in channel) { + for (percentageDouble in channel) { val newPercentage = (percentageDouble * 100).roundToInt() if (newPercentage != percentage) { print('.') @@ -111,14 +123,14 @@ class SendRecvV2E2ETest { adbRule.supportedFeatures, "0644", false, - coroutineContext = coroutineContext + coroutineContext = coroutineContext, ), this, - serial = adbRule.deviceSerial + serial = adbRule.deviceSerial, ) var percentage = 0 - for(percentageDouble in channel) { + for (percentageDouble in channel) { val newPercentage = (percentageDouble * 100).roundToInt() if (newPercentage != percentage) { print('.') @@ -128,7 +140,10 @@ class SendRecvV2E2ETest { val stats = adbRule.adb.execute(StatFileRequest("/data/local/tmp/app-debug.apk"), adbRule.deviceSerial) assertThat(stats.size).isEqualTo(testFile.length().toUInt()) - val sizeString = adbRule.adb.execute(ShellCommandRequest("${md5()} /data/local/tmp/app-debug.apk"), adbRule.deviceSerial) + val sizeString = adbRule.adb.execute( + ShellCommandRequest("${md5()} /data/local/tmp/app-debug.apk"), + adbRule.deviceSerial, + ) val split = sizeString.output.split(" ").filter { it != "" } /** @@ -137,7 +152,7 @@ class SendRecvV2E2ETest { */ assertThat(split[0]).isEqualTo(testFile.md5()) - //TODO figure out why 644 is actually pushed as 666 + // TODO figure out why 644 is actually pushed as 666 assertThat(stats.mode).isEqualTo("100666".toUInt(radix = 8)) } } diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/StatV2E2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/StatV2E2ETest.kt index a49a0e250..ccfa90668 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/StatV2E2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/feature/StatV2E2ETest.kt @@ -46,11 +46,11 @@ class StatV2E2ETest { adbRule.adb.execute( PushFileRequest(testFile, "/data/local/tmp/$fileName", coroutineContext = coroutineContext), this, - serial = adbRule.deviceSerial + serial = adbRule.deviceSerial, ) var percentage = 0 - for(percentageDouble in channel) { + for (percentageDouble in channel) { val newPercentage = (percentageDouble * 100).roundToInt() if (newPercentage != percentage) { print('.') @@ -71,7 +71,10 @@ class StatV2E2ETest { fun testListFile() { runBlocking { val stats = - adbRule.adb.execute(StatFileRequest("/data/local/tmp/app-debug.apk", adbRule.supportedFeatures), adbRule.deviceSerial) + adbRule.adb.execute( + StatFileRequest("/data/local/tmp/app-debug.apk", adbRule.supportedFeatures), + adbRule.deviceSerial, + ) assertThat(stats.size).isEqualTo(testFile.length().toULong()) } } diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/rule/AdbDeviceRule.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/rule/AdbDeviceRule.kt index 78641eb38..8b7255c8e 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/rule/AdbDeviceRule.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/rule/AdbDeviceRule.kt @@ -55,11 +55,11 @@ class AdbDeviceRule(val deviceType: DeviceType = DeviceType.ANY, vararg val requ override fun evaluate() { runBlocking { withTimeoutOrNull(initTimeout.toMillis()) { - //First we start the adb if it is not running + // First we start the adb if it is not running startAdb() - //Wait for compatible device - //boot + supported features + // Wait for compatible device + // boot + supported features val device = waitForDevice() deviceSerial = device.serial } ?: Assume.assumeTrue("Timeout waiting for device", false) @@ -80,7 +80,7 @@ class AdbDeviceRule(val deviceType: DeviceType = DeviceType.ANY, vararg val requ DeviceType.EMULATOR -> { Assume.assumeTrue( "No device of type $deviceType found", - device.serial.startsWith("emulator-") + device.serial.startsWith("emulator-"), ) } @@ -92,13 +92,13 @@ class AdbDeviceRule(val deviceType: DeviceType = DeviceType.ANY, vararg val requ Assume.assumeTrue( "No compatible device found for features $requiredFeatures", requiredFeatures.isEmpty() || - supportedFeatures.containsAll(requiredFeatures.asList()) + supportedFeatures.containsAll(requiredFeatures.asList()), ) } lineSeparator = adb.execute( ShellCommandRequest("echo"), - device.serial + device.serial, ).output return device diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/rule/DeviceType.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/rule/DeviceType.kt index 176902d23..deafdfcf4 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/rule/DeviceType.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/rule/DeviceType.kt @@ -18,5 +18,5 @@ package com.malinskiy.adam.rule enum class DeviceType { EMULATOR, - ANY -} \ No newline at end of file + ANY, +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/AndroidDebugBridgeClient.kt b/adam/src/main/kotlin/com/malinskiy/adam/AndroidDebugBridgeClient.kt index aa3629c30..fbfa67558 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/AndroidDebugBridgeClient.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/AndroidDebugBridgeClient.kt @@ -39,7 +39,7 @@ import java.net.InetSocketAddress public class AndroidDebugBridgeClient( public val port: Int, public val host: InetAddress, - public val socketFactory: SocketFactory + public val socketFactory: SocketFactory, ) : Closeable { private val socketAddress: InetSocketAddress = InetSocketAddress(host, port) @@ -47,12 +47,14 @@ public class AndroidDebugBridgeClient( val validationResponse = request.validate() if (!validationResponse.success) { val requestSimpleClassName = request.javaClass.simpleName - throw RequestValidationException("Request $requestSimpleClassName did not pass validation: ${validationResponse.message}") + throw RequestValidationException( + "Request $requestSimpleClassName did not pass validation: ${validationResponse.message}", + ) } return socketFactory.tcp( socketAddress = socketAddress, - idleTimeout = request.socketIdleTimeout + idleTimeout = request.socketIdleTimeout, ).use { socket -> serial?.let { SetDeviceRequest(it).handshake(socket) @@ -61,16 +63,22 @@ public class AndroidDebugBridgeClient( } } - public fun execute(request: AsyncChannelRequest, scope: CoroutineScope, serial: String? = null): ReceiveChannel { + public fun execute( + request: AsyncChannelRequest, + scope: CoroutineScope, + serial: String? = null, + ): ReceiveChannel { val validationResponse = request.validate() if (!validationResponse.success) { val requestSimpleClassName = request.javaClass.simpleName - throw RequestValidationException("Request $requestSimpleClassName did not pass validation: ${validationResponse.message}") + throw RequestValidationException( + "Request $requestSimpleClassName did not pass validation: ${validationResponse.message}", + ) } return scope.produce { socketFactory.tcp( socketAddress = socketAddress, - idleTimeout = request.socketIdleTimeout + idleTimeout = request.socketIdleTimeout, ).use { socket -> var backChannel = request.channel var backChannelJob: Job? = null @@ -118,7 +126,7 @@ public class AndroidDebugBridgeClient( public suspend fun execute(request: EmulatorCommandRequest): String { return socketFactory.tcp( socketAddress = request.address, - idleTimeout = request.idleTimeoutOverride + idleTimeout = request.idleTimeoutOverride, ).use { socket -> request.process(socket) } @@ -128,7 +136,9 @@ public class AndroidDebugBridgeClient( val validationResponse = request.validate() if (!validationResponse.success) { val requestSimpleClassName = request.javaClass.simpleName - throw RequestValidationException("Request $requestSimpleClassName did not pass validation: ${validationResponse.message}") + throw RequestValidationException( + "Request $requestSimpleClassName did not pass validation: ${validationResponse.message}", + ) } return request.execute(this, serial) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/AndroidDebugBridgeClientFactory.kt b/adam/src/main/kotlin/com/malinskiy/adam/AndroidDebugBridgeClientFactory.kt index c3aca814e..6d512c0b7 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/AndroidDebugBridgeClientFactory.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/AndroidDebugBridgeClientFactory.kt @@ -37,8 +37,8 @@ public class AndroidDebugBridgeClientFactory { host = host ?: InetAddress.getByName(Const.DEFAULT_ADB_HOST), socketFactory = socketFactory ?: VertxSocketFactory( idleTimeout = idleTimeout?.toMillis() ?: 30_000, - connectTimeout = connectTimeout?.toMillis() ?: 10_000 - ) + connectTimeout = connectTimeout?.toMillis() ?: 10_000, + ), ) } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/Const.kt b/adam/src/main/kotlin/com/malinskiy/adam/Const.kt index 31411b4d8..0bab0ed19 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/Const.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/Const.kt @@ -28,30 +28,44 @@ public object Const { public const val MAX_FILE_PACKET_LENGTH: Int = 64 * 1024 public const val MAX_PROTOBUF_LOGCAT_LENGTH: Int = 10_000 - public const val MAX_PROTOBUF_PACKET_LENGTH: Long = 10 * 1024 * 1024L //10Mb + public const val MAX_PROTOBUF_PACKET_LENGTH: Long = 10 * 1024 * 1024L // 10Mb public const val TEST_LOGCAT_METRIC: String = "com.malinskiy.adam.logcat" public const val ANDROID_FILE_SEPARATOR: String = "/" public val SYNC_IGNORED_FILES: Set = setOf(".", "..") public object Message { - public val OKAY: ByteArray = byteArrayOf('O'.code.toByte(), 'K'.code.toByte(), 'A'.code.toByte(), 'Y'.code.toByte()) - public val FAIL: ByteArray = byteArrayOf('F'.code.toByte(), 'A'.code.toByte(), 'I'.code.toByte(), 'L'.code.toByte()) + public val OKAY: ByteArray = + byteArrayOf('O'.code.toByte(), 'K'.code.toByte(), 'A'.code.toByte(), 'Y'.code.toByte()) + public val FAIL: ByteArray = + byteArrayOf('F'.code.toByte(), 'A'.code.toByte(), 'I'.code.toByte(), 'L'.code.toByte()) - public val DATA: ByteArray = byteArrayOf('D'.code.toByte(), 'A'.code.toByte(), 'T'.code.toByte(), 'A'.code.toByte()) - public val DONE: ByteArray = byteArrayOf('D'.code.toByte(), 'O'.code.toByte(), 'N'.code.toByte(), 'E'.code.toByte()) + public val DATA: ByteArray = + byteArrayOf('D'.code.toByte(), 'A'.code.toByte(), 'T'.code.toByte(), 'A'.code.toByte()) + public val DONE: ByteArray = + byteArrayOf('D'.code.toByte(), 'O'.code.toByte(), 'N'.code.toByte(), 'E'.code.toByte()) - public val LSTAT_V1: ByteArray = byteArrayOf('S'.code.toByte(), 'T'.code.toByte(), 'A'.code.toByte(), 'T'.code.toByte()) - public val LIST_V1: ByteArray = byteArrayOf('L'.code.toByte(), 'I'.code.toByte(), 'S'.code.toByte(), 'T'.code.toByte()) - public val DENT_V1: ByteArray = byteArrayOf('D'.code.toByte(), 'E'.code.toByte(), 'N'.code.toByte(), 'T'.code.toByte()) - public val SEND_V1: ByteArray = byteArrayOf('S'.code.toByte(), 'E'.code.toByte(), 'N'.code.toByte(), 'D'.code.toByte()) - public val RECV_V1: ByteArray = byteArrayOf('R'.code.toByte(), 'E'.code.toByte(), 'C'.code.toByte(), 'V'.code.toByte()) + public val LSTAT_V1: ByteArray = + byteArrayOf('S'.code.toByte(), 'T'.code.toByte(), 'A'.code.toByte(), 'T'.code.toByte()) + public val LIST_V1: ByteArray = + byteArrayOf('L'.code.toByte(), 'I'.code.toByte(), 'S'.code.toByte(), 'T'.code.toByte()) + public val DENT_V1: ByteArray = + byteArrayOf('D'.code.toByte(), 'E'.code.toByte(), 'N'.code.toByte(), 'T'.code.toByte()) + public val SEND_V1: ByteArray = + byteArrayOf('S'.code.toByte(), 'E'.code.toByte(), 'N'.code.toByte(), 'D'.code.toByte()) + public val RECV_V1: ByteArray = + byteArrayOf('R'.code.toByte(), 'E'.code.toByte(), 'C'.code.toByte(), 'V'.code.toByte()) - public val LIST_V2: ByteArray = byteArrayOf('L'.code.toByte(), 'I'.code.toByte(), 'S'.code.toByte(), '2'.code.toByte()) - public val DENT_V2: ByteArray = byteArrayOf('D'.code.toByte(), 'N'.code.toByte(), 'T'.code.toByte(), '2'.code.toByte()) - public val LSTAT_V2: ByteArray = byteArrayOf('L'.code.toByte(), 'S'.code.toByte(), 'T'.code.toByte(), '2'.code.toByte()) - public val RECV_V2: ByteArray = byteArrayOf('R'.code.toByte(), 'C'.code.toByte(), 'V'.code.toByte(), '2'.code.toByte()) - public val SEND_V2: ByteArray = byteArrayOf('S'.code.toByte(), 'N'.code.toByte(), 'D'.code.toByte(), '2'.code.toByte()) + public val LIST_V2: ByteArray = + byteArrayOf('L'.code.toByte(), 'I'.code.toByte(), 'S'.code.toByte(), '2'.code.toByte()) + public val DENT_V2: ByteArray = + byteArrayOf('D'.code.toByte(), 'N'.code.toByte(), 'T'.code.toByte(), '2'.code.toByte()) + public val LSTAT_V2: ByteArray = + byteArrayOf('L'.code.toByte(), 'S'.code.toByte(), 'T'.code.toByte(), '2'.code.toByte()) + public val RECV_V2: ByteArray = + byteArrayOf('R'.code.toByte(), 'C'.code.toByte(), 'V'.code.toByte(), '2'.code.toByte()) + public val SEND_V2: ByteArray = + byteArrayOf('S'.code.toByte(), 'N'.code.toByte(), 'D'.code.toByte(), '2'.code.toByte()) public val DONEDONE: ByteArray = byteArrayOf( @@ -62,7 +76,7 @@ public object Const { 'D'.code.toByte(), 'O'.code.toByte(), 'N'.code.toByte(), - 'E'.code.toByte() + 'E'.code.toByte(), ) public val FAILFAIL: ByteArray = byteArrayOf( @@ -73,7 +87,7 @@ public object Const { 'F'.code.toByte(), 'A'.code.toByte(), 'I'.code.toByte(), - 'L'.code.toByte() + 'L'.code.toByte(), ) } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/exception/PullFailedException.kt b/adam/src/main/kotlin/com/malinskiy/adam/exception/PullFailedException.kt index 898eb5a75..81ca92359 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/exception/PullFailedException.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/exception/PullFailedException.kt @@ -16,4 +16,4 @@ package com.malinskiy.adam.exception -public class PullFailedException(message: String) : RuntimeException(message) \ No newline at end of file +public class PullFailedException(message: String) : RuntimeException(message) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/exception/PushFailedException.kt b/adam/src/main/kotlin/com/malinskiy/adam/exception/PushFailedException.kt index 014864d48..8e123364b 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/exception/PushFailedException.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/exception/PushFailedException.kt @@ -16,4 +16,4 @@ package com.malinskiy.adam.exception -public class PushFailedException(message: String) : RuntimeException(message) \ No newline at end of file +public class PushFailedException(message: String) : RuntimeException(message) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/exception/RequestValidationException.kt b/adam/src/main/kotlin/com/malinskiy/adam/exception/RequestValidationException.kt index 04f7d2ace..a86c87bc5 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/exception/RequestValidationException.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/exception/RequestValidationException.kt @@ -16,4 +16,4 @@ package com.malinskiy.adam.exception -public class RequestValidationException(message: String) : RuntimeException(message) \ No newline at end of file +public class RequestValidationException(message: String) : RuntimeException(message) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedForwardingSpecException.kt b/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedForwardingSpecException.kt index e759a0f65..a595432e6 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedForwardingSpecException.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedForwardingSpecException.kt @@ -16,4 +16,6 @@ package com.malinskiy.adam.exception -public class UnsupportedForwardingSpecException(type: String) : RuntimeException("Unknown type $type for forwarding spec") \ No newline at end of file +public class UnsupportedForwardingSpecException(type: String) : RuntimeException( + "Unknown type $type for forwarding spec", +) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedImageProtocolException.kt b/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedImageProtocolException.kt index 2f4da3a16..3005679f6 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedImageProtocolException.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/exception/UnsupportedImageProtocolException.kt @@ -16,4 +16,4 @@ package com.malinskiy.adam.exception -public class UnsupportedImageProtocolException(version: Int?) : RuntimeException("Unsupported version $version") \ No newline at end of file +public class UnsupportedImageProtocolException(version: Int?) : RuntimeException("Unsupported version $version") diff --git a/adam/src/main/kotlin/com/malinskiy/adam/extension/ByteArray.kt b/adam/src/main/kotlin/com/malinskiy/adam/extension/ByteArray.kt index 640f97dd5..742496cf9 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/extension/ByteArray.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/extension/ByteArray.kt @@ -18,9 +18,9 @@ package com.malinskiy.adam.extension public fun ByteArray.toInt(): Int { return (this[0].toInt() and 0x000000FF) or - (this[1].toInt() and 0x000000FF shl 8) or - (this[2].toInt() and 0x000000FF shl 16) or - (this[3].toInt() and 0x000000FF shl 24) + (this[1].toInt() and 0x000000FF shl 8) or + (this[2].toInt() and 0x000000FF shl 16) or + (this[3].toInt() and 0x000000FF shl 24) } public fun ByteArray.toUInt(): UInt { @@ -29,13 +29,13 @@ public fun ByteArray.toUInt(): UInt { public fun ByteArray.toLong(): Long { return (this[0].toInt() and 0x000000FF).toLong() or - (this[1].toInt() and 0x000000FF shl 8).toLong() or - (this[2].toInt() and 0x000000FF shl 16).toLong() or - (this[3].toInt() and 0x000000FF shl 24).toLong() or - (this[4].toInt() and 0x000000FF shl 32).toLong() or - (this[5].toInt() and 0x000000FF shl 40).toLong() or - (this[6].toInt() and 0x000000FF shl 48).toLong() or - (this[7].toInt() and 0x000000FF shl 56).toLong() + (this[1].toInt() and 0x000000FF shl 8).toLong() or + (this[2].toInt() and 0x000000FF shl 16).toLong() or + (this[3].toInt() and 0x000000FF shl 24).toLong() or + (this[4].toInt() and 0x000000FF shl 32).toLong() or + (this[5].toInt() and 0x000000FF shl 40).toLong() or + (this[6].toInt() and 0x000000FF shl 48).toLong() or + (this[7].toInt() and 0x000000FF shl 56).toLong() } public fun ByteArray.toULong(): ULong { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/extension/Int.kt b/adam/src/main/kotlin/com/malinskiy/adam/extension/Int.kt index c5cbabb25..6049a310d 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/extension/Int.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/extension/Int.kt @@ -21,6 +21,6 @@ public fun Int.toByteArray(): ByteArray { this.ushr(24).toByte(), ((this and 0xFF0000) shr 16).toByte(), ((this and 0xFF00) shr 8).toByte(), - (this and 0xFF).toByte() + (this and 0xFF).toByte(), ) -} \ No newline at end of file +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/extension/Socket.kt b/adam/src/main/kotlin/com/malinskiy/adam/extension/Socket.kt index 30d59e82d..3474bd7bb 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/extension/Socket.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/extension/Socket.kt @@ -35,7 +35,11 @@ import kotlin.coroutines.CoroutineContext /** * Copies up to limit bytes into transformer using buffer. If limit is null - copy until EOF */ -public suspend fun Socket.copyTo(transformer: ResponseTransformer, buffer: ByteArray, limit: Long? = null): Long { +public suspend fun Socket.copyTo( + transformer: ResponseTransformer, + buffer: ByteArray, + limit: Long? = null, +): Long { var processed = 0L loop@ while (true) { val toRead = when { @@ -53,6 +57,7 @@ public suspend fun Socket.copyTo(transformer: ResponseTransformer, buffer val available = readAvailable(buffer, 0, toRead) when { processed == limit -> break@loop + available < 0 -> { break@loop } @@ -76,8 +81,15 @@ public suspend fun Socket.copyTo(transformer: ResponseTransformer, buffer * TODO: rewrite * Assumes buffer hasArray == true */ -public suspend fun Socket.copyTo(transformer: ResponseTransformer, buffer: ByteBuffer): Long = copyTo(transformer, buffer.array()) -public suspend fun Socket.copyTo(transformer: ResponseTransformer, buffer: ByteBuffer, limit: Long? = null): Long = +public suspend fun Socket.copyTo( + transformer: ResponseTransformer, + buffer: ByteBuffer, +): Long = copyTo(transformer, buffer.array()) +public suspend fun Socket.copyTo( + transformer: ResponseTransformer, + buffer: ByteBuffer, + limit: Long? = null, +): Long = copyTo(transformer, buffer.array(), limit) public suspend fun Socket.readOptionalProtocolString(): String? { @@ -109,7 +121,8 @@ public suspend fun Socket.readProtocolString(): String { if (copied != 4L) { throw RequestRejectedException("Unexpected string length: $length") } - val messageLength = length.toIntOrNull(16) ?: throw RequestRejectedException("Unexpected string length: $length") + val messageLength = + length.toIntOrNull(16) ?: throw RequestRejectedException("Unexpected string length: $length") compatClear() compatLimit(messageLength) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/interactor/AdbBinaryInteractor.kt b/adam/src/main/kotlin/com/malinskiy/adam/interactor/AdbBinaryInteractor.kt index 3878f78f0..f9d569e41 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/interactor/AdbBinaryInteractor.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/interactor/AdbBinaryInteractor.kt @@ -26,7 +26,7 @@ public open class AdbBinaryInteractor { public suspend fun execute( adbBinary: File?, androidHome: File?, - vararg cmd: String + vararg cmd: String, ): Boolean { val androidEnvHome: File? = try { System.getenv("ANDROID_HOME") ?: System.getenv("ANDROID_SDK_ROOT") diff --git a/adam/src/main/kotlin/com/malinskiy/adam/interactor/DiscoverAdbSocketInteractor.kt b/adam/src/main/kotlin/com/malinskiy/adam/interactor/DiscoverAdbSocketInteractor.kt index 28ed3a366..ef926c145 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/interactor/DiscoverAdbSocketInteractor.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/interactor/DiscoverAdbSocketInteractor.kt @@ -52,4 +52,4 @@ public class DiscoverAdbSocketInteractor { public companion object { private val log = AdamLogging.logger {} } -} \ No newline at end of file +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/interactor/StartAdbInteractor.kt b/adam/src/main/kotlin/com/malinskiy/adam/interactor/StartAdbInteractor.kt index dc78d778d..08a68cba8 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/interactor/StartAdbInteractor.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/interactor/StartAdbInteractor.kt @@ -23,6 +23,6 @@ public class StartAdbInteractor : AdbBinaryInteractor() { public suspend fun execute( adbBinary: File? = null, androidHome: File? = null, - serverPort: Int = Const.DEFAULT_ADB_PORT + serverPort: Int = Const.DEFAULT_ADB_PORT, ): Boolean = execute(adbBinary, androidHome, "-P", serverPort.toString(), "start-server") -} \ No newline at end of file +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/interactor/StopAdbInteractor.kt b/adam/src/main/kotlin/com/malinskiy/adam/interactor/StopAdbInteractor.kt index 53c3a08d2..499e49374 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/interactor/StopAdbInteractor.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/interactor/StopAdbInteractor.kt @@ -23,6 +23,6 @@ public class StopAdbInteractor : AdbBinaryInteractor() { public suspend fun execute( adbBinary: File? = null, androidHome: File? = null, - serverPort: Int = Const.DEFAULT_ADB_PORT + serverPort: Int = Const.DEFAULT_ADB_PORT, ): Boolean = execute(adbBinary, androidHome, "-P", serverPort.toString(), "kill-server") -} \ No newline at end of file +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/io/AsyncFileReader.kt b/adam/src/main/kotlin/com/malinskiy/adam/io/AsyncFileReader.kt index 9626985ce..f9eb4a5dc 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/io/AsyncFileReader.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/io/AsyncFileReader.kt @@ -40,7 +40,7 @@ public class AsyncFileReader( private val start: Long = 0, private val offset: Int = 0, private val length: Int = Const.MAX_FILE_PACKET_LENGTH, - override val coroutineContext: CoroutineContext = Dispatchers.IO + override val coroutineContext: CoroutineContext = Dispatchers.IO, ) : CoroutineScope, SuspendCloseable { private val fileChannel = file.inputStream().buffered() private val bufferChannel: Channel = Channel(capacity = 2) @@ -59,6 +59,7 @@ public class AsyncFileReader( AdamMaxFilePacketPool.recycle(byteBuffer) shouldClose = true } + else -> { byteBuffer.compatLimit(read + offset) bufferChannel.send(byteBuffer) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/io/AsyncFileWriter.kt b/adam/src/main/kotlin/com/malinskiy/adam/io/AsyncFileWriter.kt index 149a489f4..3d2b246dd 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/io/AsyncFileWriter.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/io/AsyncFileWriter.kt @@ -30,7 +30,7 @@ import kotlin.coroutines.CoroutineContext public class AsyncFileWriter( file: File, - override val coroutineContext: CoroutineContext = Dispatchers.IO + override val coroutineContext: CoroutineContext = Dispatchers.IO, ) : CoroutineScope, SuspendCloseable { private val fileChannel by lazy { if (!file.exists()) { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/log/AdamLogging.kt b/adam/src/main/kotlin/com/malinskiy/adam/log/AdamLogging.kt index 43ae14c3b..b97d60ec2 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/log/AdamLogging.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/log/AdamLogging.kt @@ -17,8 +17,8 @@ package com.malinskiy.adam.log import logcat.LogPriority -import logcat.logcat import logcat.asLog +import logcat.logcat public object AdamLogging { public fun logger(func: () -> Unit): AdamLogger = AdamLogger() @@ -84,4 +84,4 @@ public class AdamLogger { } } } -} \ No newline at end of file +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/AsyncChannelRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/AsyncChannelRequest.kt index 43d0accb8..9573e63ab 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/AsyncChannelRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/AsyncChannelRequest.kt @@ -27,7 +27,7 @@ import kotlinx.coroutines.channels.SendChannel public abstract class AsyncChannelRequest( public val channel: ReceiveChannel? = null, target: Target = NonSpecifiedTarget, - socketIdleTimeout: Long? = null + socketIdleTimeout: Long? = null, ) : Request(target, socketIdleTimeout) { /** diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/ComplexRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/ComplexRequest.kt index ce6fa81e1..88da7da48 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/ComplexRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/ComplexRequest.kt @@ -34,4 +34,4 @@ public abstract class ComplexRequest(target: Target = NonSpecifiedTarg } public abstract suspend fun readElement(socket: Socket): T -} \ No newline at end of file +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/Feature.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/Feature.kt index 10f3b7c9e..f3a9d65f1 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/Feature.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/Feature.kt @@ -99,7 +99,9 @@ public enum class Feature { /** * adbd supports dry-run send for send/recv v2. */ - SENDRECV_V2_DRY_RUN_SEND; + SENDRECV_V2_DRY_RUN_SEND, + + ; public fun value(): String = name.lowercase(Locale.ENGLISH) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/Request.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/Request.kt index 668c64f42..183b06536 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/Request.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/Request.kt @@ -32,7 +32,7 @@ import java.io.UnsupportedEncodingException */ public abstract class Request( public val target: Target = HostTarget, - public val socketIdleTimeout: Long? = null + public val socketIdleTimeout: Long? = null, ) { /** @@ -61,7 +61,7 @@ public abstract class Request( val result = String.format("%04X%s", fullRequest.length, fullRequest) .toByteArray(Const.DEFAULT_TRANSPORT_ENCODING) - //Need to set proper length in case there are multi-byte characters + // Need to set proper length in case there are multi-byte characters val actualLength = result.size - 4 String.format("%04X", actualLength).toByteArray(Const.DEFAULT_TRANSPORT_ENCODING).copyInto(result, 0, 0, 4) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/SynchronousRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/SynchronousRequest.kt index dc7c2bae8..d62cc0306 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/SynchronousRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/SynchronousRequest.kt @@ -21,7 +21,11 @@ import com.malinskiy.adam.transport.Socket import com.malinskiy.adam.transport.withMaxPacketBuffer import kotlinx.coroutines.yield -public abstract class SynchronousRequest(target: Target = NonSpecifiedTarget) : ComplexRequest(target), ResponseTransformer { +public abstract class SynchronousRequest(target: Target = NonSpecifiedTarget) : + ComplexRequest( + target, + ), + ResponseTransformer { override suspend fun readElement(socket: Socket): T { withMaxPacketBuffer { loop@ do { @@ -34,6 +38,7 @@ public abstract class SynchronousRequest(target: Target = NonSpecified yield() continue@loop } + count > 0 -> { process(data, 0, count) } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/abb/AbbExecRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/abb/AbbExecRequest.kt index b158b4d28..b037160c4 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/abb/AbbExecRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/abb/AbbExecRequest.kt @@ -26,7 +26,10 @@ import com.malinskiy.adam.transport.Socket import com.malinskiy.adam.transport.withDefaultBuffer @Features(Feature.ABB_EXEC) -public open class AbbExecRequest(private val args: List, private val supportedFeatures: List) : ComplexRequest() { +public open class AbbExecRequest( + private val args: List, + private val supportedFeatures: List, +) : ComplexRequest() { private val transformer = StringResponseTransformer() override suspend fun readElement(socket: Socket): String { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/adbd/RestartAdbdRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/adbd/RestartAdbdRequest.kt index 80ee1995d..6e2621ed6 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/adbd/RestartAdbdRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/adbd/RestartAdbdRequest.kt @@ -22,7 +22,11 @@ import com.malinskiy.adam.request.transform.StringResponseTransformer public class RestartAdbdRequest(private val mode: AdbdMode) : SynchronousRequest() { private val transformer = StringResponseTransformer() - override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = transformer.process(bytes, offset, limit) + override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = transformer.process( + bytes, + offset, + limit, + ) override fun serialize(): ByteArray = createBaseRequest(mode.requestString) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/device/AsyncDeviceMonitorRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/device/AsyncDeviceMonitorRequest.kt index 28306653e..431fc6167 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/device/AsyncDeviceMonitorRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/device/AsyncDeviceMonitorRequest.kt @@ -22,7 +22,10 @@ import com.malinskiy.adam.request.HostTarget import com.malinskiy.adam.transport.Socket import kotlinx.coroutines.channels.SendChannel -public class AsyncDeviceMonitorRequest : AsyncChannelRequest, Unit>(target = HostTarget, socketIdleTimeout = Long.MAX_VALUE) { +public class AsyncDeviceMonitorRequest : AsyncChannelRequest, Unit>( + target = HostTarget, + socketIdleTimeout = Long.MAX_VALUE, +) { override suspend fun readElement(socket: Socket, sendChannel: SendChannel>): Boolean { val data = socket.readProtocolString() @@ -34,9 +37,9 @@ public class AsyncDeviceMonitorRequest : AsyncChannelRequest, Unit> val split = line.split("\t") Device( serial = split[0], - state = DeviceState.from(split[1]) + state = DeviceState.from(split[1]), ) - } + }, ) return false } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/device/ListDevicesRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/device/ListDevicesRequest.kt index 89413548e..5eecae881 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/device/ListDevicesRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/device/ListDevicesRequest.kt @@ -32,7 +32,7 @@ public class ListDevicesRequest : ComplexRequest>(target = HostTarg val split = line.split("\t") Device( serial = split[0], - state = DeviceState.from(split[1]) + state = DeviceState.from(split[1]), ) } } @@ -51,7 +51,8 @@ public enum class DeviceState { UNAUTHORIZED, AUTHORIZING, CONNECTING, - UNKNOWN; + UNKNOWN, + ; public companion object { public fun from(value: String): DeviceState = diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/emu/EmulatorCommandRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/emu/EmulatorCommandRequest.kt index 46575f444..71ddbc6e0 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/emu/EmulatorCommandRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/emu/EmulatorCommandRequest.kt @@ -43,7 +43,7 @@ public class EmulatorCommandRequest( public val address: InetSocketAddress, private val authToken: String? = null, private val cleanResponse: Boolean = true, - public val idleTimeoutOverride: Long? = null + public val idleTimeoutOverride: Long? = null, ) { private suspend fun readAuthToken(): String? { val authTokenFile = File(System.getProperty("user.home"), ".emulator_console_auth_token") @@ -81,6 +81,7 @@ public class EmulatorCommandRequest( count == 0 -> { continue@loop } + count > 0 -> { output.append(String(buffer, 0, count, Charsets.UTF_8)) } @@ -94,6 +95,7 @@ public class EmulatorCommandRequest( * Additional confirmation of auth */ token.isNotBlank() -> output.indexOf(OUTPUT_DELIMITER, firstOkPosition + 1) + else -> firstOkPosition } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/file/ListFilesRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/file/ListFilesRequest.kt index aecc56199..a751896ee 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/file/ListFilesRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/file/ListFilesRequest.kt @@ -19,18 +19,19 @@ package com.malinskiy.adam.request.sync import com.malinskiy.adam.request.shell.v1.ShellCommandResult import com.malinskiy.adam.request.shell.v1.SyncShellCommandRequest - public class ListFilesRequest(private val directory: String) : SyncShellCommandRequest>( - cmd = "ls -l $directory" + cmd = "ls -l $directory", ) { - private val lslRegex: Regex = ("^([bcdlsp-][-r][-w][-xsS][-r][-w][-xsS][-r][-w][-xstST])\\s+" + //permissions - "(?:\\d+\\s+)?" + //nlink - "(\\S+)\\s+" + //user - "(\\S+)\\s+" + //group - "([\\d\\s,]*)\\s+" + //size - "(\\d{4}-\\d\\d-\\d\\d)\\s+" + //date - "(\\d\\d:\\d\\d)\\s+" + //time - "(.*)$").toRegex() // + private val lslRegex: Regex = ( + "^([bcdlsp-][-r][-w][-xsS][-r][-w][-xsS][-r][-w][-xstST])\\s+" + // permissions + "(?:\\d+\\s+)?" + // nlink + "(\\S+)\\s+" + // user + "(\\S+)\\s+" + // group + "([\\d\\s,]*)\\s+" + // size + "(\\d{4}-\\d\\d-\\d\\d)\\s+" + // date + "(\\d\\d:\\d\\d)\\s+" + // time + "(.*)$" + ).toRegex() // override fun convertResult(response: ShellCommandResult): List { return response.output @@ -77,7 +78,7 @@ public class ListFilesRequest(private val directory: String) : SyncShellCommandR name = name, directory = directory, type = type, - link = link + link = link, ) } } @@ -116,5 +117,5 @@ public data class AndroidFile( public val directory: String, public val size: Long, public val type: AndroidFileType, - public val link: String? = null + public val link: String? = null, ) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/ListPortForwardsRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/ListPortForwardsRequest.kt index 30b1adca1..3ab407d6c 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/ListPortForwardsRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/ListPortForwardsRequest.kt @@ -21,7 +21,9 @@ import com.malinskiy.adam.request.ComplexRequest import com.malinskiy.adam.request.SerialTarget import com.malinskiy.adam.transport.Socket -public class ListPortForwardsRequest(serial: String) : ComplexRequest>(target = SerialTarget(serial)) { +public class ListPortForwardsRequest(serial: String) : ComplexRequest>( + target = SerialTarget(serial), +) { override suspend fun readElement(socket: Socket): List { return socket.readProtocolString().lines().mapNotNull { line -> if (line.isNotEmpty()) { @@ -29,7 +31,7 @@ public class ListPortForwardsRequest(serial: String) : ComplexRequest(target = SerialTarget(serial)) { @@ -49,5 +49,5 @@ public class PortForwardRequest( public enum class PortForwardingMode(public val value: String) { DEFAULT(""), - NO_REBIND(":norebind") + NO_REBIND(":norebind"), } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/PortForwardingRule.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/PortForwardingRule.kt index e7fdae394..d7dff29f4 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/PortForwardingRule.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/PortForwardingRule.kt @@ -19,5 +19,5 @@ package com.malinskiy.adam.request.forwarding public data class PortForwardingRule( public val serial: String, public val localSpec: LocalPortSpec, - public val remoteSpec: RemotePortSpec -) \ No newline at end of file + public val remoteSpec: RemotePortSpec, +) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/RemoveAllPortForwardsRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/RemoveAllPortForwardsRequest.kt index b28b9bddd..498399af1 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/RemoveAllPortForwardsRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/forwarding/RemoveAllPortForwardsRequest.kt @@ -25,4 +25,4 @@ public class RemoveAllPortForwardsRequest(serial: String) : SynchronousRequest(target = SerialTarget(serial)) { override fun serialize(): ByteArray = createBaseRequest("killforward:${local.toSpec()}") diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/BufferedImageScreenCaptureAdapter.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/BufferedImageScreenCaptureAdapter.kt index 1b267f9a1..19645c043 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/BufferedImageScreenCaptureAdapter.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/BufferedImageScreenCaptureAdapter.kt @@ -24,7 +24,7 @@ import java.nio.ByteBuffer public class BufferedImageScreenCaptureAdapter( private var recycledImage: BufferedImage? = null, buffer: ByteBuffer? = null, - colorModelFactory: ColorModelFactory = ColorModelFactory() + colorModelFactory: ColorModelFactory = ColorModelFactory(), ) : ScreenCaptureAdapter(colorModelFactory = colorModelFactory, buffer = buffer) { override suspend fun process( @@ -42,7 +42,7 @@ public class BufferedImageScreenCaptureAdapter( alphaOffset: Int, alphaLength: Int, colorSpace: ColorSpace?, - socket: Socket + socket: Socket, ): BufferedImage { val imageBuffer: ByteBuffer = read(socket, size) imageBuffer.compatRewind() @@ -53,10 +53,15 @@ public class BufferedImageScreenCaptureAdapter( val shortArray = ShortArray(imageBuffer.limit() / 2) imageBuffer.asShortBuffer().get(shortArray) it.raster.setDataElements( - 0, 0, width, height, shortArray + 0, + 0, + width, + height, + shortArray, ) } } + 32 -> { if (alphaOffset == 24 && alphaLength == 8 && blueOffset == 16 && blueLength == 8 && @@ -69,7 +74,11 @@ public class BufferedImageScreenCaptureAdapter( createOrReuseBufferedImage(colorSpace, width, height, BufferedImage.TYPE_4BYTE_ABGR) .also { it.raster.setDataElements( - 0, 0, width, height, imageBuffer.array() + 0, + 0, + width, + height, + imageBuffer.array(), ) } } else { @@ -86,7 +95,7 @@ public class BufferedImageScreenCaptureAdapter( blueOffset, blueLength, alphaOffset, - alphaLength + alphaLength, ) it.raster.setDataElements(x, y, bytes) } @@ -94,7 +103,10 @@ public class BufferedImageScreenCaptureAdapter( } } } - else -> throw UnsupportedOperationException("BufferedImageScreenCaptureAdapter only works with 16 and 32 bit images") + + else -> throw UnsupportedOperationException( + "BufferedImageScreenCaptureAdapter only works with 16 and 32 bit images", + ) } } @@ -102,7 +114,7 @@ public class BufferedImageScreenCaptureAdapter( colorSpace: ColorSpace?, width: Int, height: Int, - type: Int + type: Int, ): BufferedImage { val bufferedImage = when (val profileName = colorSpace?.getProfileName()) { null -> { @@ -117,6 +129,7 @@ public class BufferedImageScreenCaptureAdapter( BufferedImage(width, height, type) } } + else -> { val colorModel = colorModelFactory.get(profileName, type) val localRecycledImage = recycledImage diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ColorModelFactory.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ColorModelFactory.kt index c9a1865d8..b477e778f 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ColorModelFactory.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ColorModelFactory.kt @@ -48,18 +48,20 @@ public class ColorModelFactory { true, false, Transparency.TRANSLUCENT, - DataBuffer.TYPE_BYTE + DataBuffer.TYPE_BYTE, ) } + BufferedImage.TYPE_3BYTE_BGR -> { ComponentColorModel( colorSpace, false, false, Transparency.TRANSLUCENT, - DataBuffer.TYPE_BYTE + DataBuffer.TYPE_BYTE, ) } + BufferedImage.TYPE_INT_ARGB -> { DirectColorModel( colorSpace, @@ -69,14 +71,13 @@ public class ColorModelFactory { 0x000000ff, -0x1000000, false, - DataBuffer.TYPE_INT + DataBuffer.TYPE_INT, ) } + else -> throw RuntimeException("Unsupported buffered image type $type") } return colorModel.also { cache[profileName] = it } } } - - } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ColorSpace.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ColorSpace.kt index 50e97ad00..e9216822c 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ColorSpace.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ColorSpace.kt @@ -19,7 +19,8 @@ package com.malinskiy.adam.request.framebuffer public enum class ColorSpace { UNKNOWN, SRGB, - P3; + P3, + ; public fun getProfileName(): String? = when (this) { UNKNOWN -> null diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/RawImage.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/RawImage.kt index 061dee892..cd7004812 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/RawImage.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/RawImage.kt @@ -18,7 +18,6 @@ package com.malinskiy.adam.request.framebuffer import java.awt.image.BufferedImage - public data class RawImage( public val version: Int, public val bitsPerPixel: Int, @@ -34,18 +33,19 @@ public data class RawImage( public val greenLength: Int, public val alphaOffset: Int, public val alphaLength: Int, - public val buffer: ByteArray + public val buffer: ByteArray, ) { public fun getARGB(index: Int): Int { return when (bitsPerPixel) { 16 -> { Color.RGB565_2BYTE.toARGB8888_INT(buffer[index], buffer[index + 1]) } + 32 -> { val value = (buffer[index].toInt() and 0x00FF) or - (buffer[index + 1].toInt() and 0x00FF shl 8) or - (buffer[index + 2].toInt() and 0x00FF shl 16) or - (buffer[index + 3].toInt() and 0x00FF shl 24) + (buffer[index + 1].toInt() and 0x00FF shl 8) or + (buffer[index + 2].toInt() and 0x00FF shl 16) or + (buffer[index + 3].toInt() and 0x00FF shl 24) Color.ARGB_INT.toARGB8888_INT( value = value, redOffset = redOffset, @@ -55,9 +55,10 @@ public data class RawImage( blueOffset = blueOffset, blueLength = blueLength, alphaOffset = alphaOffset, - alphaLength = alphaLength + alphaLength = alphaLength, ) } + else -> { throw UnsupportedOperationException("RawImage.getARGB(int) only works in 16 and 32 bit mode.") } @@ -72,6 +73,7 @@ public data class RawImage( null -> { BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB) } + else -> { val colorModel = ColorModelFactory().get(profileName, BufferedImage.TYPE_INT_ARGB) val raster = colorModel.createCompatibleWritableRaster(width, height) @@ -89,4 +91,3 @@ public data class RawImage( return bufferedImage } } - diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/RawImageScreenCaptureAdapter.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/RawImageScreenCaptureAdapter.kt index 46f828a41..9f827f099 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/RawImageScreenCaptureAdapter.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/RawImageScreenCaptureAdapter.kt @@ -19,7 +19,9 @@ package com.malinskiy.adam.request.framebuffer import com.malinskiy.adam.transport.Socket import java.nio.ByteBuffer -public class RawImageScreenCaptureAdapter(buffer: ByteBuffer? = null) : ScreenCaptureAdapter(buffer = buffer) { +public class RawImageScreenCaptureAdapter(buffer: ByteBuffer? = null) : ScreenCaptureAdapter( + buffer = buffer, +) { override suspend fun process( version: Int, @@ -36,7 +38,7 @@ public class RawImageScreenCaptureAdapter(buffer: ByteBuffer? = null) : ScreenCa alphaOffset: Int, alphaLength: Int, colorSpace: ColorSpace?, - socket: Socket + socket: Socket, ): RawImage { val imageBuffer = read(socket, size) @@ -55,7 +57,7 @@ public class RawImageScreenCaptureAdapter(buffer: ByteBuffer? = null) : ScreenCa blueLength = blueLength, alphaOffset = alphaOffset, alphaLength = alphaLength, - buffer = imageBuffer.array() + buffer = imageBuffer.array(), ) } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureAdapter.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureAdapter.kt index 9d47e8bed..c62032ded 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureAdapter.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureAdapter.kt @@ -29,7 +29,7 @@ import java.nio.ByteBuffer */ public abstract class ScreenCaptureAdapter( private var buffer: ByteBuffer? = null, - protected val colorModelFactory: ColorModelFactory = ColorModelFactory() + protected val colorModelFactory: ColorModelFactory = ColorModelFactory(), ) { public suspend fun read(socket: Socket, size: Int): ByteBuffer { val localBuffer = buffer @@ -61,6 +61,6 @@ public abstract class ScreenCaptureAdapter( alphaOffset: Int, alphaLength: Int, colorSpace: ColorSpace? = null, - socket: Socket + socket: Socket, ): T } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequest.kt index d7e441c80..0e5b4b297 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequest.kt @@ -35,9 +35,15 @@ public class ScreenCaptureRequest(private val adapter: ScreenCaptureAdapter 12 // bpp, size, width, height, 4*(length, offset) - 2 -> 13 // bpp, colorSpace, size, width, height, 4*(length, offset) - 16 -> 3 // compatibility mode: size, width, height. used previously to denote framebuffer depth + 1 -> 12 + + // bpp, size, width, height, 4*(length, offset) + 2 -> 13 + + // bpp, colorSpace, size, width, height, 4*(length, offset) + 16 -> 3 + + // compatibility mode: size, width, height. used previously to denote framebuffer depth /** * See https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/master/daemon/framebuffer_service.cpp#42 * for a possible new value for DDMS_RAWIMAGE_VERSION @@ -66,8 +72,9 @@ public class ScreenCaptureRequest(private val adapter: ScreenCaptureAdapter adapter.process( version = protocolVersion, bitsPerPixel = int, @@ -82,8 +89,9 @@ public class ScreenCaptureRequest(private val adapter: ScreenCaptureAdapter adapter.process( version = protocolVersion, bitsPerPixel = int, @@ -99,8 +107,9 @@ public class ScreenCaptureRequest(private val adapter: ScreenCaptureAdapter throw UnsupportedImageProtocolException(protocolVersion) } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/SyncLogcatRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/SyncLogcatRequest.kt index 758f76b54..7da6ea3e8 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/SyncLogcatRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/SyncLogcatRequest.kt @@ -26,19 +26,21 @@ public class SyncLogcatRequest( buffers: List = listOf(LogcatBuffer.default), pid: Long? = null, lastReboot: Boolean? = null, - filters: List = emptyList() + filters: List = emptyList(), ) : SyncShellCommandRequest( cmd = "logcat" + - " -d" + - (since?.let { + " -d" + + ( + since?.let { " -t ${since.text}" - } ?: "") + - " ${modes.joinToString(separator = " ") { "-v $it" }}" + - " ${buffers.joinToString(separator = " ") { "-b $it" }}" + - (pid?.let { " --pid=$it" } ?: "") + - (lastReboot?.let { " -L" } ?: "") + - " ${filters.joinToString(separator = " ") { "${it.tag}:${it.level.name}" }}" - .trimEnd() + } ?: "" + ) + + " ${modes.joinToString(separator = " ") { "-v $it" }}" + + " ${buffers.joinToString(separator = " ") { "-b $it" }}" + + (pid?.let { " --pid=$it" } ?: "") + + (lastReboot?.let { " -L" } ?: "") + + " ${filters.joinToString(separator = " ") { "${it.tag}:${it.level.name}" }}" + .trimEnd(), ) { override fun convertResult(response: ShellCommandResult): String = response.output } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/ListMdnsServicesRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/ListMdnsServicesRequest.kt index e7319afb6..8577f1a52 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/ListMdnsServicesRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/ListMdnsServicesRequest.kt @@ -23,7 +23,6 @@ import com.malinskiy.adam.transport.Socket public class ListMdnsServicesRequest : ComplexRequest>(target = HostTarget) { override suspend fun readElement(socket: Socket): List { - return socket.readProtocolString().lines() .filterNot { it.isEmpty() } .map { @@ -31,7 +30,7 @@ public class ListMdnsServicesRequest : ComplexRequest>(target MdnsService( name = split[0].trim(), serviceType = split[1].trim(), - url = split[2].trim() + url = split[2].trim(), ) } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsService.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsService.kt index 869aeb393..858f2f81e 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsService.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsService.kt @@ -19,5 +19,5 @@ package com.malinskiy.adam.request.mdns public data class MdnsService( public val name: String, public val serviceType: String, - public val url: String + public val url: String, ) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsStatus.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsStatus.kt index be63afecf..f9a42cd4f 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsStatus.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/mdns/MdnsStatus.kt @@ -18,5 +18,5 @@ package com.malinskiy.adam.request.mdns public data class MdnsStatus( public val available: Boolean, - public val version: String? = null + public val version: String? = null, ) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ConnectDeviceRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ConnectDeviceRequest.kt index 71ac6cbd6..cd0bfee0d 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ConnectDeviceRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ConnectDeviceRequest.kt @@ -26,7 +26,7 @@ import com.malinskiy.adam.transport.Socket */ public class ConnectDeviceRequest( private val host: String, - private val port: Int = 5555 + private val port: Int = 5555, ) : ComplexRequest(target = HostTarget) { override fun serialize(): ByteArray = createBaseRequest("connect:$host:$port") diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/DisconnectDeviceRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/DisconnectDeviceRequest.kt index 765cd6296..4e06891de 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/DisconnectDeviceRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/DisconnectDeviceRequest.kt @@ -29,7 +29,7 @@ import com.malinskiy.adam.transport.Socket */ public class DisconnectDeviceRequest( private val host: String? = null, - private val port: Int? = 5555 + private val port: Int? = 5555, ) : ComplexRequest(target = HostTarget) { override fun serialize(): ByteArray = createBaseRequest( @@ -41,7 +41,7 @@ public class DisconnectDeviceRequest( } else { "$host" } - }" + }", ) override suspend fun readElement(socket: Socket): String = socket.readProtocolString() diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ExecInRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ExecInRequest.kt index 3dc603b31..b2c6c772e 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ExecInRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ExecInRequest.kt @@ -30,24 +30,31 @@ public class ExecInRequest( private val cmd: String, private val channel: ReceiveChannel, private val sizeChannel: SendChannel, - socketIdleTimeout: Long? = null + socketIdleTimeout: Long? = null, ) : ComplexRequest(socketIdleTimeout = socketIdleTimeout) { override suspend fun readElement(socket: Socket) { while (true) { if (!channel.isClosedForReceive) { - //Should not request more if read channel is already closed + // Should not request more if read channel is already closed sizeChannel.send(Const.MAX_FILE_PACKET_LENGTH) } val result = channel.tryReceive() when { - result.isSuccess && result.getOrThrow().isNotEmpty() -> socket.writeFully(result.getOrThrow(), 0, result.getOrThrow().size) + result.isSuccess && result.getOrThrow().isNotEmpty() -> socket.writeFully( + result.getOrThrow(), + 0, + result.getOrThrow().size, + ) + result.isClosed -> break + result.isFailure -> continue + else -> break } } - //Have to poll + // Have to poll socket.readStatus() } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/PairDeviceRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/PairDeviceRequest.kt index 150bef4fe..6f6e00e62 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/PairDeviceRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/PairDeviceRequest.kt @@ -29,10 +29,10 @@ import com.malinskiy.adam.transport.Socket */ public class PairDeviceRequest( private val url: String, - private val pairingCode: String + private val pairingCode: String, ) : ComplexRequest(target = HostTarget) { override suspend fun readElement(socket: Socket): String = socket.readProtocolString() override fun serialize(): ByteArray = createBaseRequest("pair:$pairingCode:$url") -} \ No newline at end of file +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/RebootRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/RebootRequest.kt index 27d5bc2e5..6fc51c9f8 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/RebootRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/RebootRequest.kt @@ -31,5 +31,5 @@ public enum class RebootMode(public val value: String) { RECOVERY("recovery"), BOOTLOADER("bootloader"), SIDELOAD("sideload"), - SIDELOAD_AUTO_REBOOT("sideload-auto-reboot") + SIDELOAD_AUTO_REBOOT("sideload-auto-reboot"), } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ReconnectRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ReconnectRequest.kt index 8757b0ef9..cf5bd87f6 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ReconnectRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/ReconnectRequest.kt @@ -37,7 +37,7 @@ import com.malinskiy.adam.transport.withDefaultBuffer */ public class ReconnectRequest( private val reconnectTarget: ReconnectTarget? = null, - target: Target = NonSpecifiedTarget + target: Target = NonSpecifiedTarget, ) : ComplexRequest(target = target) { override suspend fun readElement(socket: Socket): String { withDefaultBuffer { @@ -47,7 +47,7 @@ public class ReconnectRequest( return if (array().copyOfRange(0, 4).contentEquals(done)) { "done" } else { - //This is length of a response string + // This is length of a response string val size = String(array(), 0, 4, Const.DEFAULT_TRANSPORT_ENCODING).toInt(radix = 16) compatClear() compatLimit(size) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/RemountPartitionsRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/RemountPartitionsRequest.kt index bf4c9080f..4fbc47114 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/misc/RemountPartitionsRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/misc/RemountPartitionsRequest.kt @@ -22,14 +22,18 @@ import com.malinskiy.adam.request.transform.StringResponseTransformer public class RemountPartitionsRequest(private val autoReboot: Boolean = false) : SynchronousRequest() { private val transformer = StringResponseTransformer() - override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = transformer.process(bytes, offset, limit) + override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = transformer.process( + bytes, + offset, + limit, + ) override fun serialize(): ByteArray = createBaseRequest( when (autoReboot) { true -> "remount:-R" false -> "remount:" - } + }, ) override fun transform(): String = transformer.transform() -} \ No newline at end of file +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/AtomicInstallPackageRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/AtomicInstallPackageRequest.kt index 398c8869e..fc720e364 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/AtomicInstallPackageRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/AtomicInstallPackageRequest.kt @@ -51,9 +51,12 @@ public class AtomicInstallPackageRequest( private val supportedFeatures: List, private val reinstall: Boolean, private val extraArgs: List = emptyList(), - public val coroutineContext: CoroutineContext = Dispatchers.IO + public val coroutineContext: CoroutineContext = Dispatchers.IO, ) : AccumulatingMultiRequest() { - override suspend fun execute(androidDebugBridgeClient: AndroidDebugBridgeClient, serial: String?): String = with(androidDebugBridgeClient) { + override suspend fun execute( + androidDebugBridgeClient: AndroidDebugBridgeClient, + serial: String?, + ): String = with(androidDebugBridgeClient) { val (parentSessionId, output) = execute(CreateMultiPackageSessionRequest(pkgList, supportedFeatures, reinstall, extraArgs), serial) output.addToResponse() @@ -64,23 +67,33 @@ public class AtomicInstallPackageRequest( val (childSessionId, output) = execute( CreateIndividualPackageSessionRequest(pkg, pkgList, supportedFeatures, reinstall, extraArgs), - serial + serial, ) output.addToResponse() when (pkg) { is SingleFileInstallationPackage -> { execute( - WriteIndividualPackageRequest(pkg.file, supportedFeatures, childSessionId, coroutineContext), - serial + WriteIndividualPackageRequest( + pkg.file, + supportedFeatures, + childSessionId, + coroutineContext, + ), + serial, ).addToResponse() } is ApkSplitInstallationPackage -> { for (file in pkg.fileList) { execute( - WriteIndividualPackageRequest(file, supportedFeatures, childSessionId, coroutineContext), - serial + WriteIndividualPackageRequest( + file, + supportedFeatures, + childSessionId, + coroutineContext, + ), + serial, ).addToResponse() } } @@ -96,7 +109,7 @@ public class AtomicInstallPackageRequest( try { execute(InstallCommitRequest(parentSessionId, supportedFeatures, abandon = true), serial) } catch (e: Exception) { - //Ignore + // Ignore } throw e } @@ -113,7 +126,8 @@ public class AtomicInstallPackageRequest( is SingleFileInstallationPackage -> listOf(it.file) is ApkSplitInstallationPackage -> it.fileList } - }.flatten().any { file -> file.extension == "apex" } && !supportedFeatures.contains(Feature.APEX)) { + }.flatten().any { file -> file.extension == "apex" } && !supportedFeatures.contains(Feature.APEX) + ) { ValidationResponse(false, ValidationResponse.missingFeature(Feature.APEX)) } else { ValidationResponse.Success diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/InstallRemotePackageRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/InstallRemotePackageRequest.kt index d3529c727..2419f6538 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/InstallRemotePackageRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/InstallRemotePackageRequest.kt @@ -22,7 +22,7 @@ import com.malinskiy.adam.request.shell.v1.ShellCommandRequest public class InstallRemotePackageRequest( private val absoluteRemoteFilePath: String, reinstall: Boolean, - extraArgs: List = emptyList() + extraArgs: List = emptyList(), ) : ShellCommandRequest( cmd = StringBuilder().apply { append("pm install ") @@ -37,7 +37,7 @@ public class InstallRemotePackageRequest( } append(absoluteRemoteFilePath) - }.toString() + }.toString(), ) { override fun validate(): ValidationResponse { val result = super.validate() @@ -46,7 +46,10 @@ public class InstallRemotePackageRequest( } else if (absoluteRemoteFilePath.endsWith(".apex")) { ValidationResponse(false, "APEX packages are only not compatible with InstallRemotePackageRequest") } else if (!absoluteRemoteFilePath.endsWith(".apk")) { - ValidationResponse(false, "Unsupported package extension ${absoluteRemoteFilePath.substringAfterLast('.')}. Should be apk") + ValidationResponse( + false, + "Unsupported package extension ${absoluteRemoteFilePath.substringAfterLast('.')}. Should be apk", + ) } else { ValidationResponse.Success } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/InstallSplitPackageRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/InstallSplitPackageRequest.kt index d235474e5..ab534d1d5 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/InstallSplitPackageRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/InstallSplitPackageRequest.kt @@ -54,29 +54,34 @@ public class InstallSplitPackageRequest( private val supportedFeatures: List, private val reinstall: Boolean, private val extraArgs: List = emptyList(), - public val coroutineContext: CoroutineContext = Dispatchers.IO + public val coroutineContext: CoroutineContext = Dispatchers.IO, ) : AccumulatingMultiRequest() { private val totalSize: Long by lazy { pkg.fileList.sumOf { it.length() } } - override suspend fun execute(androidDebugBridgeClient: AndroidDebugBridgeClient, serial: String?): String = with(androidDebugBridgeClient) { + override suspend fun execute(androidDebugBridgeClient: AndroidDebugBridgeClient, serial: String?): String = with( + androidDebugBridgeClient, + ) { val (sessionId, output) = execute( CreateIndividualPackageSessionRequest( pkg, listOf(pkg), supportedFeatures, reinstall, - extraArgs + "-S${totalSize}" + extraArgs + "-S$totalSize", ), - serial + serial, ) output.addToResponse() try { for (file in pkg.fileList) { - execute(WriteIndividualPackageRequest(file, supportedFeatures, sessionId, coroutineContext), serial).addToResponse() + execute( + WriteIndividualPackageRequest(file, supportedFeatures, sessionId, coroutineContext), + serial, + ).addToResponse() } execute(InstallCommitRequest(sessionId, supportedFeatures), serial).addToResponse() @@ -85,7 +90,7 @@ public class InstallSplitPackageRequest( try { execute(InstallCommitRequest(sessionId, supportedFeatures, abandon = true), serial) } catch (e: Exception) { - //Ignore + // Ignore } throw e } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/LegacySideloadRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/LegacySideloadRequest.kt index 48f725778..3778eb914 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/LegacySideloadRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/LegacySideloadRequest.kt @@ -32,7 +32,7 @@ import kotlin.coroutines.CoroutineContext */ public class LegacySideloadRequest( private val pkg: File, - public val coroutineContext: CoroutineContext = Dispatchers.IO + public val coroutineContext: CoroutineContext = Dispatchers.IO, ) : ComplexRequest() { override fun validate(): ValidationResponse { val message = diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/PmListRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/PmListRequest.kt index c94e85e61..62cd434f3 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/PmListRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/PmListRequest.kt @@ -24,7 +24,7 @@ public class PmListRequest(private val includePath: Boolean = false) : SyncShell append("pm list packages") if (includePath) append(" -f") - }.toString() + }.toString(), ) { override fun convertResult(response: ShellCommandResult): List { return response.output @@ -38,11 +38,11 @@ public class PmListRequest(private val includePath: Boolean = false) : SyncShell true -> { Package(split[2], split[1]) } + false -> { Package(split[1]) } } - } } } @@ -50,5 +50,5 @@ public class PmListRequest(private val includePath: Boolean = false) : SyncShell public data class Package( public val name: String, - public val path: String? = null + public val path: String? = null, ) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/SideloadRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/SideloadRequest.kt index 62586a47d..2be4332f1 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/SideloadRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/SideloadRequest.kt @@ -42,12 +42,14 @@ public class SideloadRequest( val bytes = buffer.copyOfRange(0, 8) when { bytes.contentEquals(Const.Message.DONEDONE) -> return true + bytes.contentEquals(Const.Message.FAILFAIL) -> return false + else -> { val blockId = String(bytes, 0, 8, Const.DEFAULT_TRANSPORT_ENCODING).toLong() val offset = blockId * blockSize if (offset != currentOffset) { - //We can't seek on the channels. Recreating the channel again + // We can't seek on the channels. Recreating the channel again reader?.close() reader = AsyncFileReader(pkg, start = offset) reader.start() @@ -90,5 +92,5 @@ public class SideloadRequest( return ValidationResponse(message == null, message) } - override fun serialize(): ByteArray = createBaseRequest("sideload-host:${pkg.length()}:${blockSize}") + override fun serialize(): ByteArray = createBaseRequest("sideload-host:${pkg.length()}:$blockSize") } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/StreamingPackageInstallRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/StreamingPackageInstallRequest.kt index c1180b323..e81be358d 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/StreamingPackageInstallRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/StreamingPackageInstallRequest.kt @@ -45,7 +45,7 @@ public class StreamingPackageInstallRequest( private val supportedFeatures: List, private val reinstall: Boolean, private val extraArgs: List = emptyList(), - public val coroutineContext: CoroutineContext = Dispatchers.IO + public val coroutineContext: CoroutineContext = Dispatchers.IO, ) : ComplexRequest() { private val transformer = StringResponseTransformer() @@ -81,7 +81,7 @@ public class StreamingPackageInstallRequest( "package" } else { "exec:cmd package" - } + }, ) add("install") diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/UninstallRemotePackageRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/UninstallRemotePackageRequest.kt index 5c59c1ac4..b7ab21a5f 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/UninstallRemotePackageRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/UninstallRemotePackageRequest.kt @@ -26,7 +26,7 @@ import com.malinskiy.adam.request.shell.v1.ShellCommandRequest */ public class UninstallRemotePackageRequest( packageName: String, - keepData: Boolean = false + keepData: Boolean = false, ) : ShellCommandRequest( cmd = StringBuilder().apply { append("pm uninstall ") @@ -36,5 +36,5 @@ public class UninstallRemotePackageRequest( } append(packageName) - }.toString() + }.toString(), ) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/AddSessionRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/AddSessionRequest.kt index bc3860578..69f3cb243 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/AddSessionRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/AddSessionRequest.kt @@ -26,7 +26,7 @@ import com.malinskiy.adam.transport.Socket public class AddSessionRequest( private val childSessions: List, private val parentSession: String, - private val supportedFeatures: List + private val supportedFeatures: List, ) : ComplexRequest() { override fun serialize(): ByteArray { val hasAbbExec = supportedFeatures.contains(Feature.ABB_EXEC) @@ -36,7 +36,7 @@ public class AddSessionRequest( "package" } else { "exec:cmd package" - } + }, ) add("install-add-session") add(parentSession) @@ -55,7 +55,7 @@ public class AddSessionRequest( if (!response.contains("Success")) { throw RequestRejectedException( "Failed to add child sessions ${childSessions.joinToString()} to a parent session " + - "$parentSession: $response" + "$parentSession: $response", ) } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateIndividualPackageSessionRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateIndividualPackageSessionRequest.kt index e1bf611eb..65473980d 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateIndividualPackageSessionRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateIndividualPackageSessionRequest.kt @@ -29,7 +29,7 @@ public class CreateIndividualPackageSessionRequest( private val pkgList: List, private val supportedFeatures: List, private val reinstall: Boolean, - private val extraArgs: List = emptyList() + private val extraArgs: List = emptyList(), ) : ComplexRequest() { override fun serialize(): ByteArray { @@ -38,10 +38,12 @@ public class CreateIndividualPackageSessionRequest( add( when { supportedFeatures.contains(Feature.ABB_EXEC) -> "package" + supportedFeatures.contains(Feature.CMD) -> "exec:cmd package" - //User is responsible for checking if pm supports install-write in this case + + // User is responsible for checking if pm supports install-write in this case else -> "exec:pm" - } + }, ) add("install-create") diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateMultiPackageSessionRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateMultiPackageSessionRequest.kt index 37262ba5f..8ef93d55c 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateMultiPackageSessionRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/CreateMultiPackageSessionRequest.kt @@ -32,7 +32,7 @@ public class CreateMultiPackageSessionRequest( private val pkgList: List, private val supportedFeatures: List, private val reinstall: Boolean, - private val extraArgs: List = emptyList() + private val extraArgs: List = emptyList(), ) : ComplexRequest() { override fun validate(): ValidationResponse { val response = super.validate() @@ -84,7 +84,7 @@ public class CreateMultiPackageSessionRequest( "package" } else { "exec:cmd package" - } + }, ) add("install-create") diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/InstallCommitRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/InstallCommitRequest.kt index 5f8dcb2b5..2cf0a6734 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/InstallCommitRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/InstallCommitRequest.kt @@ -26,7 +26,7 @@ import com.malinskiy.adam.transport.Socket public class InstallCommitRequest( private val parentSession: String, private val supportedFeatures: List, - private val abandon: Boolean = false + private val abandon: Boolean = false, ) : ComplexRequest() { override fun serialize(): ByteArray { val hasAbbExec = supportedFeatures.contains(Feature.ABB_EXEC) @@ -34,10 +34,12 @@ public class InstallCommitRequest( add( when { supportedFeatures.contains(Feature.ABB_EXEC) -> "package" + supportedFeatures.contains(Feature.CMD) -> "exec:cmd package" - //User is responsible for checking if pm supports install-write in this case + + // User is responsible for checking if pm supports install-write in this case else -> "exec:pm" - } + }, ) if (abandon) { @@ -58,8 +60,8 @@ public class InstallCommitRequest( override suspend fun readElement(socket: Socket): String { val result = socket.readStatus() - //Rather than checking for success, we check for Failure since some implementations of PackageManagerShellCommand ignore the - //logSuccess=true in doCommitSession + // Rather than checking for success, we check for Failure since some implementations of PackageManagerShellCommand ignore the + // logSuccess=true in doCommitSession if (result.contains("Failure")) { throw RequestRejectedException("Failed to finalize session $parentSession: $result") } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/WriteIndividualPackageRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/WriteIndividualPackageRequest.kt index 090e40032..153d16236 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/WriteIndividualPackageRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/pkg/multi/WriteIndividualPackageRequest.kt @@ -31,7 +31,7 @@ public class WriteIndividualPackageRequest( private val file: File, private val supportedFeatures: List, private val session: String, - private val coroutineContext: CoroutineContext = Dispatchers.IO + private val coroutineContext: CoroutineContext = Dispatchers.IO, ) : ComplexRequest() { override fun serialize(): ByteArray { val hasAbbExec = supportedFeatures.contains(Feature.ABB_EXEC) @@ -39,10 +39,12 @@ public class WriteIndividualPackageRequest( add( when { supportedFeatures.contains(Feature.ABB_EXEC) -> "package" + supportedFeatures.contains(Feature.CMD) -> "exec:cmd package" - //User is responsible for checking if pm supports install-write in this case + + // User is responsible for checking if pm supports install-write in this case else -> "exec:pm" - } + }, ) add("install-write") diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ListReversePortForwardsRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ListReversePortForwardsRequest.kt index 8d6376437..7bb06b635 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ListReversePortForwardsRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ListReversePortForwardsRequest.kt @@ -26,7 +26,9 @@ import com.malinskiy.adam.transport.Socket /** * Doesn't work with SerialTarget, have to use the serial as a parameter for the execute method */ -public class ListReversePortForwardsRequest : ComplexRequest>(target = NonSpecifiedTarget) { +public class ListReversePortForwardsRequest : ComplexRequest>( + target = NonSpecifiedTarget, +) { override suspend fun readElement(socket: Socket): List { return socket.readProtocolString().lines().mapNotNull { line -> if (line.isNotEmpty()) { @@ -34,7 +36,7 @@ public class ListReversePortForwardsRequest : ComplexRequest(targ override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = Unit override fun transform(): Unit = Unit -} \ No newline at end of file +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/RemoveReversePortForwardRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/RemoveReversePortForwardRequest.kt index 51cd98347..5088e7ca0 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/RemoveReversePortForwardRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/RemoveReversePortForwardRequest.kt @@ -24,11 +24,11 @@ import com.malinskiy.adam.request.forwarding.RemotePortSpec * Doesn't work with SerialTarget, have to use the serial as a parameter for the execute method */ public class RemoveReversePortForwardRequest( - private val local: RemotePortSpec + private val local: RemotePortSpec, ) : SynchronousRequest(target = NonSpecifiedTarget) { override fun serialize(): ByteArray = createBaseRequest("reverse:killforward:${local.toSpec()}") override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = Unit override fun transform(): Unit = Unit -} \ No newline at end of file +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardRequest.kt index 34c8ad752..f0725d576 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardRequest.kt @@ -34,7 +34,7 @@ import com.malinskiy.adam.transport.Socket public class ReversePortForwardRequest( private val local: RemotePortSpec, private val remote: LocalPortSpec, - private val mode: PortForwardingMode = PortForwardingMode.DEFAULT + private val mode: PortForwardingMode = PortForwardingMode.DEFAULT, ) : ComplexRequest(target = NonSpecifiedTarget) { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardingRule.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardingRule.kt index 8b076a914..acbde8420 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardingRule.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardingRule.kt @@ -22,5 +22,5 @@ import com.malinskiy.adam.request.forwarding.RemotePortSpec public data class ReversePortForwardingRule( public val serial: String, public val localSpec: RemotePortSpec, - public val remoteSpec: LocalPortSpec -) \ No newline at end of file + public val remoteSpec: LocalPortSpec, +) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/security/SetDmVerityCheckingRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/security/SetDmVerityCheckingRequest.kt index 18017dae7..4b33f1d7c 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/security/SetDmVerityCheckingRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/security/SetDmVerityCheckingRequest.kt @@ -28,14 +28,18 @@ import com.malinskiy.adam.request.transform.StringResponseTransformer public class SetDmVerityCheckingRequest(private val enabled: Boolean) : SynchronousRequest() { private val transformer = StringResponseTransformer() - override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = transformer.process(bytes, offset, limit) + override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = transformer.process( + bytes, + offset, + limit, + ) override fun serialize(): ByteArray = createBaseRequest( when (enabled) { true -> "enable-verity:" false -> "disable-verity:" - } + }, ) override fun transform(): String = transformer.transform() -} \ No newline at end of file +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/AsyncCompatShellCommandRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/AsyncCompatShellCommandRequest.kt index bdda429dd..a68faa0d1 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/AsyncCompatShellCommandRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/AsyncCompatShellCommandRequest.kt @@ -44,13 +44,15 @@ public abstract class AsyncCompatShellCommandRequest( override suspend fun execute( androidDebugBridgeClient: AndroidDebugBridgeClient, - serial: String? + serial: String?, ): ReceiveChannel { return when { supportedFeatures.contains(Feature.SHELL_V2) -> { val channel = Channel() val receiveChannel = androidDebugBridgeClient.execute( - V2ChanneledShellCommandRequest(cmd, channel, target, socketIdleTimeout), coroutineScope, serial, + V2ChanneledShellCommandRequest(cmd, channel, target, socketIdleTimeout), + coroutineScope, + serial, ) coroutineScope.produce { for (chunk in receiveChannel) { @@ -62,7 +64,9 @@ public abstract class AsyncCompatShellCommandRequest( else -> { val receiveChannel: ReceiveChannel = androidDebugBridgeClient.execute( - ChanneledShellCommandRequest(cmd, target, socketIdleTimeout), coroutineScope, serial, + ChanneledShellCommandRequest(cmd, target, socketIdleTimeout), + coroutineScope, + serial, ) coroutineScope.produce { for (line in receiveChannel) { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ChanneledShellCommandRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ChanneledShellCommandRequest.kt index dce7bbffa..c3bb9bc62 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ChanneledShellCommandRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ChanneledShellCommandRequest.kt @@ -27,7 +27,7 @@ import kotlinx.coroutines.channels.SendChannel public open class ChanneledShellCommandRequest( public val cmd: String, target: Target = NonSpecifiedTarget, - socketIdleTimeout: Long? = null + socketIdleTimeout: Long? = null, ) : AsyncChannelRequest(target = target, socketIdleTimeout = socketIdleTimeout) { override suspend fun readElement(socket: Socket, sendChannel: SendChannel): Boolean { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellCommandResult.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellCommandResult.kt index 022d11d19..629626525 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellCommandResult.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellCommandResult.kt @@ -20,7 +20,7 @@ import com.malinskiy.adam.Const public data class ShellCommandResult( public val stdout: ByteArray, - public val exitCode: Int + public val exitCode: Int, ) { public val output: String by lazy { String(stdout, Const.DEFAULT_TRANSPORT_ENCODING) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellResultResponseTransformer.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellResultResponseTransformer.kt index 5821b56d6..341d5851b 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellResultResponseTransformer.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v1/ShellResultResponseTransformer.kt @@ -36,10 +36,11 @@ public class ShellResultResponseTransformer : ResponseTransformer(public val cmd: String, public abstract fun convertResult(response: ShellCommandResult): T private val responseTransformer = ShellResultResponseTransformer() - override suspend fun process(bytes: ByteArray, offset: Int, limit: Int): Unit = responseTransformer.process(bytes, offset, limit) + override suspend fun process( + bytes: ByteArray, + offset: Int, + limit: Int, + ): Unit = responseTransformer.process(bytes, offset, limit) override fun transform(): T = convertResult(responseTransformer.transform()) override fun serialize(): ByteArray = createBaseRequest("shell:$cmd;echo ${EXIT_CODE_DELIMITER}$?") public companion object { public const val EXIT_CODE_DELIMITER: Char = 'x' } -} \ No newline at end of file +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ChanneledShellCommandRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ChanneledShellCommandRequest.kt index ef0025119..5012597a6 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ChanneledShellCommandRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ChanneledShellCommandRequest.kt @@ -32,7 +32,7 @@ public open class ChanneledShellCommandRequest( ) : AsyncChannelRequest( target = target, channel = channel, - socketIdleTimeout = socketIdleTimeout + socketIdleTimeout = socketIdleTimeout, ) { override suspend fun readElement(socket: Socket, sendChannel: SendChannel): Boolean { @@ -60,7 +60,7 @@ public open class ChanneledShellCommandRequest( } MessageType.EXIT -> { - //ignoredLength + // ignoredLength socket.readIntLittleEndian() val exitCode = socket.readByte().toInt() sendChannel.send(ShellCommandResultChunk(exitCode = exitCode)) @@ -96,7 +96,7 @@ public open class ChanneledShellCommandRequest( public data class ShellCommandResultChunk( public val stdout: ByteArray? = null, public val stderr: ByteArray? = null, - public val exitCode: Int? = null + public val exitCode: Int? = null, ) { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -107,11 +107,15 @@ public data class ShellCommandResultChunk( if (stdout != null) { if (other.stdout == null) return false if (!stdout.contentEquals(other.stdout)) return false - } else if (other.stdout != null) return false + } else if (other.stdout != null) { + return false + } if (stderr != null) { if (other.stderr == null) return false if (!stderr.contentEquals(other.stderr)) return false - } else if (other.stderr != null) return false + } else if (other.stderr != null) { + return false + } if (exitCode != other.exitCode) return false return true @@ -127,7 +131,7 @@ public data class ShellCommandResultChunk( public data class ShellCommandInputChunk( public val stdin: ByteArray? = null, - public val close: Boolean = false + public val close: Boolean = false, ) { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -138,7 +142,9 @@ public data class ShellCommandInputChunk( if (stdin != null) { if (other.stdin == null) return false if (!stdin.contentEquals(other.stdin)) return false - } else if (other.stdin != null) return false + } else if (other.stdin != null) { + return false + } if (close != other.close) return false return true diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/MessageType.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/MessageType.kt index 8894d4a77..aa21b92e9 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/MessageType.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/MessageType.kt @@ -35,7 +35,9 @@ public enum class MessageType { /** * Indicates an invalid or unknown packet */ - INVALID; + INVALID, + + ; public fun toValue(): Int = when (this) { STDIN -> 0 @@ -58,4 +60,4 @@ public enum class MessageType { else -> INVALID } } -} \ No newline at end of file +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandRequest.kt index 0a15997a3..61fc36b39 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandRequest.kt @@ -19,4 +19,4 @@ package com.malinskiy.adam.request.shell.v2 public open class ShellCommandRequest(cmd: String, socketIdleTimeout: Long? = null) : SyncShellCommandRequest(cmd, socketIdleTimeout = socketIdleTimeout) { override fun convertResult(response: ShellCommandResult): ShellCommandResult = response -} \ No newline at end of file +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandResult.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandResult.kt index 8ea2c3877..5f3962676 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandResult.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandResult.kt @@ -21,7 +21,7 @@ import com.malinskiy.adam.Const public data class ShellCommandResult( public val stdout: ByteArray, public val stderr: ByteArray, - public val exitCode: Int + public val exitCode: Int, ) { public val output: String by lazy { String(stdout, Const.DEFAULT_TRANSPORT_ENCODING) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/SyncShellCommandRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/SyncShellCommandRequest.kt index c7c67d2d9..8ad3f56fd 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/SyncShellCommandRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/shell/v2/SyncShellCommandRequest.kt @@ -27,7 +27,11 @@ import com.malinskiy.adam.transport.withMaxPacketBuffer /** * shell v2 service required for this request */ -public abstract class SyncShellCommandRequest(public val cmd: String, target: Target = NonSpecifiedTarget, socketIdleTimeout: Long? = null) : +public abstract class SyncShellCommandRequest( + public val cmd: String, + target: Target = NonSpecifiedTarget, + socketIdleTimeout: Long? = null, +) : ComplexRequest(target, socketIdleTimeout) { private val stdoutBuilder = ByteStreams.newDataOutput() @@ -66,7 +70,7 @@ public abstract class SyncShellCommandRequest(public val cmd: String, } MessageType.EXIT -> { - //ignoredLength + // ignoredLength socket.readIntLittleEndian() exitCode = socket.readByte().toInt() break@loop @@ -82,7 +86,7 @@ public abstract class SyncShellCommandRequest(public val cmd: String, val shellCommandResult = ShellCommandResult( stdout = stdoutBuilder.toByteArray(), stderr = stderrBuilder.toByteArray(), - exitCode = exitCode + exitCode = exitCode, ) return convertResult(shellCommandResult) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/BFFSearch.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/BFFSearch.kt index b0f97092d..e72b0e995 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/BFFSearch.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/BFFSearch.kt @@ -22,7 +22,13 @@ internal class BFFSearch { suspend fun execute( source: S, destination: D, - visitor: suspend (currentDir: S, newDirs: MutableList, newFiles: MutableList, newTargetDirs: MutableList, destinationRoot: D) -> Unit + visitor: suspend ( + currentDir: S, + newDirs: MutableList, + newFiles: MutableList, + newTargetDirs: MutableList, + destinationRoot: D, + ) -> Unit, ): Pair, List> { /** * Iterate instead of recursion @@ -32,7 +38,7 @@ internal class BFFSearch { var directoriesToTraverse = listOf(source) while (directoriesToTraverse.isNotEmpty()) { - //We have to use a second collection because we're iterating over directoriesToTraverse + // We have to use a second collection because we're iterating over directoriesToTraverse val currentDepthDirs = mutableListOf() for (dir in directoriesToTraverse) { visitor(dir, currentDepthDirs, fileList, dirList, destination) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/PullRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/PullRequest.kt index dfa6caa9f..a7547950e 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/PullRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/PullRequest.kt @@ -51,7 +51,7 @@ public class PullRequest( private val source: String, private val destination: File, private val supportedFeatures: List, - override val coroutineContext: CoroutineContext = Dispatchers.IO + override val coroutineContext: CoroutineContext = Dispatchers.IO, ) : MultiRequest(), CoroutineScope { /** @@ -69,8 +69,8 @@ public class PullRequest( } remoteFileEntry.isRegularFile() || - remoteFileEntry.isBlockDevice() || - remoteFileEntry.isCharDevice() -> { + remoteFileEntry.isBlockDevice() || + remoteFileEntry.isCharDevice() -> { doPullFile(source, destination, remoteFileEntry.size().toLong(), serial) } @@ -78,16 +78,17 @@ public class PullRequest( throw PushFailedException( "Source $source exists and is not a directory or a file: mode=${ remoteFileEntry.mode.toString( - 8 + 8, ) - }" + }", ) } !remoteFileEntry.exists() -> { throw PushFailedException("Source $source doesn't exist") } - //We exhausted all conditions above. This is just to make the compiler happy + + // We exhausted all conditions above. This is just to make the compiler happy else -> false } } @@ -102,8 +103,8 @@ public class PullRequest( } remoteFileEntry.isRegularFile() || - remoteFileEntry.isBlockDevice() || - remoteFileEntry.isCharDevice() -> { + remoteFileEntry.isBlockDevice() || + remoteFileEntry.isCharDevice() -> { val name = source.substringAfterLast(Const.ANDROID_FILE_SEPARATOR) doPullFile(source, File(destination, name), remoteFileEntry.size().toLong(), serial) } @@ -112,16 +113,17 @@ public class PullRequest( throw PushFailedException( "Source $source exists and is not a directory or a file: mode=${ remoteFileEntry.mode.toString( - 8 + 8, ) - }" + }", ) } !remoteFileEntry.exists() -> { throw PushFailedException("Source $source doesn't exist") } - //We exhausted all conditions above. This is just to make the compiler happy + + // We exhausted all conditions above. This is just to make the compiler happy else -> false } } @@ -138,17 +140,17 @@ public class PullRequest( private suspend fun AndroidDebugBridgeClient.pullFolder( destination: File, - serial: String? + serial: String?, ): Boolean { - val (filesToPull, _) = BFFSearch().execute( source, - destination + destination, ) { currentDir, newDirs, newFiles, _, destinationRoot -> val ls = execute(CompatListFileRequest(currentDir, supportedFeatures), serial) for (file in ls.filterNot { Const.SYNC_IGNORED_FILES.contains(it.name) }) { when { file.isDirectory() -> newDirs.add(currentDir + Const.ANDROID_FILE_SEPARATOR + file.name) + file.isRegularFile() && file.size() == 0L.toULong() -> { val remotePath = currentDir + Const.ANDROID_FILE_SEPARATOR + file.name val remoteRelativePath = remotePath.substringAfter(source) @@ -168,8 +170,8 @@ public class PullRequest( remote = remotePath, mtime = file.mtime.epochSecond, mode = file.mode, - size = file.size() - ) + size = file.size(), + ), ) } } @@ -191,11 +193,11 @@ public class PullRequest( source: String, realDestination: File, size: Long, - serial: String? + serial: String?, ): Boolean { val channel = execute( CompatPullFileRequest(source, realDestination, supportedFeatures, this@PullRequest, size, coroutineContext), - serial + serial, ) var progress = 0.0 for (update in channel) { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/PushRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/PushRequest.kt index 61de396f4..bc603eeef 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/PushRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/PushRequest.kt @@ -49,7 +49,7 @@ public class PushRequest( private val destination: String, private val supportedFeatures: List, private val mode: String = "0777", - override val coroutineContext: CoroutineContext = Dispatchers.IO + override val coroutineContext: CoroutineContext = Dispatchers.IO, ) : MultiRequest(), CoroutineScope { /** @@ -63,57 +63,67 @@ public class PushRequest( source.isFile -> { when { remoteFileEntry.isDirectory() -> { - //Put into folder + // Put into folder doPushFile( source, - destination.removeSuffix(Const.ANDROID_FILE_SEPARATOR) + Const.ANDROID_FILE_SEPARATOR + source.name, + destination.removeSuffix(Const.ANDROID_FILE_SEPARATOR) + Const.ANDROID_FILE_SEPARATOR + + source.name, mode, - serial + serial, ) } + remoteFileEntry.isRegularFile() || !remoteFileEntry.exists() -> { doPushFile(source, destination, mode, serial) } + else -> { throw PushFailedException( "Target $destination exists and is not a directory or a file: mode=${ remoteFileEntry.mode.toString( - 8 + 8, ) - }" + }", ) } } } + source.isDirectory -> { when { remoteFileEntry.isDirectory() -> { - //Put into subfolder + // Put into subfolder pushFolder( - destination.removeSuffix(Const.ANDROID_FILE_SEPARATOR) + Const.ANDROID_FILE_SEPARATOR + source.name, - serial + destination.removeSuffix(Const.ANDROID_FILE_SEPARATOR) + Const.ANDROID_FILE_SEPARATOR + + source.name, + serial, ) } + remoteFileEntry.isRegularFile() -> { throw PushFailedException("Can't push folder $source: target $destination is a file") } + !remoteFileEntry.exists() -> { pushFolder(destination.removeSuffix(Const.ANDROID_FILE_SEPARATOR), serial) } + else -> { throw PushFailedException( "Target $destination exists and is not a directory or a file: mode=${ remoteFileEntry.mode.toString( - 8 + 8, ) - }" + }", ) } } } + !source.exists() -> { throw PushFailedException("Source $source doesn't exist") } + else -> { throw PushFailedException("Source $source is not a directory or a file") } @@ -126,7 +136,7 @@ public class PushRequest( private suspend fun AndroidDebugBridgeClient.pushFolder(destination: String, serial: String?): Boolean { val (filesToPush, dirsToCreate) = BFFSearch().execute( source, - destination + destination, ) { currentDir, newDirs, newFiles, newTargetDirs, destinationRoot -> val ls = currentDir.listFiles()?.filterNot { Const.SYNC_IGNORED_FILES.contains(it.name) } if (ls.isNullOrEmpty()) return@execute @@ -138,6 +148,7 @@ public class PushRequest( newTargetDirs.add(destinationRoot + Const.ANDROID_FILE_SEPARATOR + remoteRelativePath) newDirs.add(file) } + file.isFile -> { newFiles.add( SyncFile( @@ -145,8 +156,8 @@ public class PushRequest( remote = destinationRoot + Const.ANDROID_FILE_SEPARATOR + remoteRelativePath, mtime = file.lastModified() / 1000, mode = mode.toUInt(8) and "0777".toUInt(8), - size = file.length().toULong() - ) + size = file.length().toULong(), + ), ) } } @@ -170,7 +181,7 @@ public class PushRequest( private suspend fun AndroidDebugBridgeClient.createRemoteDirectories( destination: String, serial: String?, - dirsToCreate: List + dirsToCreate: List, ) { execute(ShellCommandRequest("mkdir -p ${listOf(destination).bashEscape()}"), serial) @@ -179,7 +190,7 @@ public class PushRequest( val limit = 1024 * 4 for (dir in dirsToCreate) { val escapedDirArg = " ${listOf(dir).bashEscape()}" - //This check might fail for multi-byte encodings + // This check might fail for multi-byte encodings if (cmdBuilder.length + escapedDirArg.length > limit) { execute(ShellCommandRequest(cmdBuilder.toString()), serial) cmdBuilder.clear() @@ -200,11 +211,11 @@ public class PushRequest( source: File, destination: String, mode: String, - serial: String? + serial: String?, ): Boolean { val channel = execute( CompatPushFileRequest(source, destination, supportedFeatures, this@PushRequest, mode, coroutineContext), - serial + serial, ) var progress = 0.0 for (update in channel) { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/base/BasePullFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/base/BasePullFileRequest.kt index dbee6bcfe..0b336b4ed 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/base/BasePullFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/base/BasePullFileRequest.kt @@ -41,7 +41,7 @@ public abstract class BasePullFileRequest( private val remotePath: String, local: File, private val size: Long? = null, - coroutineContext: CoroutineContext = Dispatchers.IO + coroutineContext: CoroutineContext = Dispatchers.IO, ) : AsyncChannelRequest() { private val fileWriter = AsyncFileWriter(local, coroutineContext) @@ -50,7 +50,7 @@ public abstract class BasePullFileRequest( override suspend fun handshake(socket: Socket) { super.handshake(socket) - //If we don't have expected size, fetch it + // If we don't have expected size, fetch it totalBytes = size ?: StatFileRequest(remotePath).readElement(socket).size.toLong() if (totalBytes > 0) { fileWriter.start() @@ -73,6 +73,7 @@ public abstract class BasePullFileRequest( } true } + header.contentEquals(Const.Message.DATA) -> { val available = data.copyOfRange(4, 8).toInt() if (available > Const.MAX_FILE_PACKET_LENGTH) { @@ -88,6 +89,7 @@ public abstract class BasePullFileRequest( sendChannel.send(currentPosition.toDouble() / totalBytes) false } + header.contentEquals(Const.Message.FAIL) -> { val size = data.copyOfRange(4, 8).toInt() compatClear() @@ -98,14 +100,15 @@ public abstract class BasePullFileRequest( val errorMessage = String(array(), 0, size) throw PullFailedException("Failed to pull file $remotePath: $errorMessage") } + else -> { throw UnsupportedSyncProtocolException( "Unexpected header message ${ String( header, - Const.DEFAULT_TRANSPORT_ENCODING + Const.DEFAULT_TRANSPORT_ENCODING, ) - }" + }", ) } } @@ -132,5 +135,4 @@ public abstract class BasePullFileRequest( } override suspend fun writeElement(element: Unit, socket: Socket): Unit = Unit - } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/base/BasePushFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/base/BasePushFileRequest.kt index 60698cc90..99c24cb17 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/base/BasePushFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/base/BasePushFileRequest.kt @@ -36,14 +36,14 @@ public abstract class BasePushFileRequest( private val local: File, protected val remotePath: String, protected val mode: String = "0777", - coroutineContext: CoroutineContext = Dispatchers.IO + coroutineContext: CoroutineContext = Dispatchers.IO, ) : AsyncChannelRequest() { protected val fileReader: AsyncFileReader = AsyncFileReader( file = local, start = 0, offset = 8, length = Const.MAX_FILE_PACKET_LENGTH - 8, - coroutineContext = coroutineContext + coroutineContext = coroutineContext, ) protected var totalBytes: Long = local.length() protected var currentPosition: Long = 0L @@ -73,9 +73,12 @@ public abstract class BasePushFileRequest( sendChannel.send(1.0) true } else { - throw PushFailedException("adb didn't acknowledge the file transfer: ${transportResponse.message ?: ""}") + throw PushFailedException( + "adb didn't acknowledge the file transfer: ${transportResponse.message ?: ""}", + ) } } + buffer.limit() > 0 -> { Const.Message.DATA.copyInto(buffer.array()) val available = buffer.limit() - 8 @@ -88,6 +91,7 @@ public abstract class BasePushFileRequest( sendChannel.send(currentPosition.toDouble() / totalBytes) false } + else -> false } } finally { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatListFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatListFileRequest.kt index 725c89b8b..0cf5411d5 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatListFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatListFileRequest.kt @@ -25,14 +25,15 @@ import com.malinskiy.adam.request.sync.v2.ListFileRequest as ListV2FileRequest public class CompatListFileRequest( private val path: String, - private val supportedFeatures: List + private val supportedFeatures: List, ) : MultiRequest>() { override suspend fun execute(androidDebugBridgeClient: AndroidDebugBridgeClient, serial: String?): List { return when { supportedFeatures.contains(Feature.LS_V2) -> androidDebugBridgeClient.execute( ListV2FileRequest(path, supportedFeatures), - serial + serial, ) + else -> androidDebugBridgeClient.execute(ListFileRequest(path), serial) } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatPullFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatPullFileRequest.kt index 45a7b6b07..0e3f3642e 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatPullFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatPullFileRequest.kt @@ -36,22 +36,26 @@ public class CompatPullFileRequest( private val supportedFeatures: List, private val coroutineScope: CoroutineScope, private val size: Long? = null, - private val coroutineContext: CoroutineContext = Dispatchers.IO + private val coroutineContext: CoroutineContext = Dispatchers.IO, ) : MultiRequest>() { - override suspend fun execute(androidDebugBridgeClient: AndroidDebugBridgeClient, serial: String?): ReceiveChannel { + override suspend fun execute( + androidDebugBridgeClient: AndroidDebugBridgeClient, + serial: String?, + ): ReceiveChannel { return when { supportedFeatures.contains(Feature.SENDRECV_V2) -> { androidDebugBridgeClient.execute( PullV2FileRequest(source, realDestination, supportedFeatures, size, coroutineContext), coroutineScope, - serial + serial, ) } + else -> { androidDebugBridgeClient.execute( PullFileRequest(source, realDestination, size, coroutineContext), coroutineScope, - serial + serial, ) } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatPushFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatPushFileRequest.kt index a555e39cb..74d89433d 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatPushFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatPushFileRequest.kt @@ -33,22 +33,26 @@ public class CompatPushFileRequest( private val supportedFeatures: List, private val coroutineScope: CoroutineScope, private val mode: String = "0777", - private val coroutineContext: CoroutineContext = Dispatchers.IO + private val coroutineContext: CoroutineContext = Dispatchers.IO, ) : MultiRequest>() { - override suspend fun execute(androidDebugBridgeClient: AndroidDebugBridgeClient, serial: String?): ReceiveChannel { + override suspend fun execute( + androidDebugBridgeClient: AndroidDebugBridgeClient, + serial: String?, + ): ReceiveChannel { return when { supportedFeatures.contains(Feature.SENDRECV_V2) -> { androidDebugBridgeClient.execute( PushV2FileRequest(source, destination, supportedFeatures, mode, false, coroutineContext), coroutineScope, - serial + serial, ) } + else -> { androidDebugBridgeClient.execute( PushFileRequest(source, destination, mode, coroutineContext), coroutineScope, - serial + serial, ) } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatStatFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatStatFileRequest.kt index 832235386..0055d9c2a 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatStatFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/compat/CompatStatFileRequest.kt @@ -25,14 +25,15 @@ import com.malinskiy.adam.request.sync.v2.StatFileRequest as StatV2FileRequest public class CompatStatFileRequest( private val source: String, - private val supportedFeatures: List + private val supportedFeatures: List, ) : MultiRequest() { override suspend fun execute(androidDebugBridgeClient: AndroidDebugBridgeClient, serial: String?): FileEntry { return when { supportedFeatures.contains(Feature.STAT_V2) -> androidDebugBridgeClient.execute( StatV2FileRequest(source, supportedFeatures), - serial + serial, ) + else -> androidDebugBridgeClient.execute(StatFileRequest(source), serial) } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/model/FileEntry.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/model/FileEntry.kt index 2579635c5..04a038cfb 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/model/FileEntry.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/model/FileEntry.kt @@ -42,7 +42,7 @@ public data class FileEntryV1( override val name: String? = null, override val mode: UInt, public val size: UInt, - override val mtime: Instant + override val mtime: Instant, ) : FileEntry() { override fun exists(): Boolean = !(size == 0.toUInt() && mode == 0.toUInt() && mtime.epochSecond == 0L) } @@ -59,7 +59,7 @@ public data class FileEntryV2( public val atime: Instant, override val mtime: Instant, public val ctime: Instant, - override val name: String? = null + override val name: String? = null, ) : FileEntry() { override fun exists(): Boolean = !(size == 0.toULong() && mode == 0.toUInt() && mtime.epochSecond == 0L) } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/model/SyncFile.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/model/SyncFile.kt index 597c8c310..cb9751d01 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/model/SyncFile.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/model/SyncFile.kt @@ -23,5 +23,5 @@ internal data class SyncFile( val remote: String, val mtime: Long, val mode: UInt, - val size: ULong + val size: ULong, ) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/ListFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/ListFileRequest.kt index 91ef34dd2..6eead1a8b 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/ListFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/ListFileRequest.kt @@ -27,7 +27,7 @@ import com.malinskiy.adam.transport.withDefaultBuffer import java.time.Instant public class ListFileRequest( - private val remotePath: String + private val remotePath: String, ) : ComplexRequest>() { override fun validate(): ValidationResponse { @@ -45,7 +45,6 @@ public class ListFileRequest( val data = array() val result = mutableListOf() loop@ while (true) { - socket.readFully(data, 0, 4) when { data.copyOfRange(0, 4).contentEquals(Const.Message.DENT_V1) -> { @@ -61,11 +60,13 @@ public class ListFileRequest( mode = mode, size = size, mtime = mtime, - name = String(data, 0, nameLength, Const.DEFAULT_TRANSPORT_ENCODING) - ) + name = String(data, 0, nameLength, Const.DEFAULT_TRANSPORT_ENCODING), + ), ) } + data.copyOfRange(0, 4).contentEquals(Const.Message.DONE) -> break@loop + else -> break@loop } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/PullFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/PullFileRequest.kt index 8e9eb5f88..7851ce188 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/PullFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/PullFileRequest.kt @@ -31,7 +31,7 @@ public class PullFileRequest( private val remotePath: String, local: File, size: Long? = null, - coroutineContext: CoroutineContext = Dispatchers.IO + coroutineContext: CoroutineContext = Dispatchers.IO, ) : BasePullFileRequest(remotePath, local, size, coroutineContext) { override suspend fun handshake(socket: Socket) { super.handshake(socket) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/PushFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/PushFileRequest.kt index fbb1ffa50..1234d04c2 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/PushFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/PushFileRequest.kt @@ -30,7 +30,7 @@ public class PushFileRequest( local: File, remotePath: String, mode: String = "0777", - coroutineContext: CoroutineContext = Dispatchers.IO + coroutineContext: CoroutineContext = Dispatchers.IO, ) : BasePushFileRequest(local, remotePath, mode, coroutineContext) { override suspend fun handshake(socket: Socket) { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/StatFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/StatFileRequest.kt index b13e05a01..bd88baa9a 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/StatFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v1/StatFileRequest.kt @@ -31,7 +31,7 @@ import com.malinskiy.adam.transport.withDefaultBuffer import java.time.Instant public class StatFileRequest( - private val remotePath: String + private val remotePath: String, ) : ComplexRequest() { override suspend fun readElement(socket: Socket): FileEntryV1 { socket.writeSyncRequest(Const.Message.LSTAT_V1, remotePath) @@ -47,7 +47,7 @@ public class StatFileRequest( return FileEntryV1( mode = bytes.copyOfRange(4, 8).toUInt(), size = bytes.copyOfRange(8, 12).toUInt(), - mtime = Instant.ofEpochSecond(bytes.copyOfRange(12, 16).toInt().toLong()) + mtime = Instant.ofEpochSecond(bytes.copyOfRange(12, 16).toInt().toLong()), ) } } @@ -62,4 +62,3 @@ public class StatFileRequest( override fun serialize(): ByteArray = createBaseRequest("sync:") } - diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/CompressionType.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/CompressionType.kt index 4e3ccb904..9cb0bc631 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/CompressionType.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/CompressionType.kt @@ -20,7 +20,8 @@ public enum class CompressionType { NONE, BROTLI, LZ4, - Zstd; + Zstd, + ; public fun toFlag(): Int = when (this) { NONE -> 0 diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/ListFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/ListFileRequest.kt index f4ffbcea4..491048ffc 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/ListFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/ListFileRequest.kt @@ -34,7 +34,7 @@ import java.time.Instant @Features(Feature.LS_V2) public class ListFileRequest( private val remotePath: String, - private val supportedFeatures: List + private val supportedFeatures: List, ) : ComplexRequest>() { override fun validate(): ValidationResponse { @@ -89,11 +89,13 @@ public class ListFileRequest( atime = atime, mtime = mtime, ctime = ctime, - name = String(data, 0, nameLength, Const.DEFAULT_TRANSPORT_ENCODING) - ) + name = String(data, 0, nameLength, Const.DEFAULT_TRANSPORT_ENCODING), + ), ) } + data.copyOfRange(0, 4).contentEquals(Const.Message.DONE) -> break@loop + else -> break@loop } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/PullFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/PullFileRequest.kt index 03221fd5f..ab5b163ea 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/PullFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/PullFileRequest.kt @@ -36,7 +36,7 @@ public class PullFileRequest( local: File, private val supportedFeatures: List, size: Long? = null, - coroutineContext: CoroutineContext = Dispatchers.IO + coroutineContext: CoroutineContext = Dispatchers.IO, ) : BasePullFileRequest(remotePath, local, size, coroutineContext) { /** * We don't have support for any compression, so the only value is NONE diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/PushFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/PushFileRequest.kt index c51816a47..b5ab19dde 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/PushFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/PushFileRequest.kt @@ -37,7 +37,7 @@ public class PushFileRequest( public val supportedFeatures: List, mode: String = "0777", public val dryRun: Boolean = false, - coroutineContext: CoroutineContext = Dispatchers.IO + coroutineContext: CoroutineContext = Dispatchers.IO, ) : BasePushFileRequest(local, remotePath, mode, coroutineContext) { /** * We don't have support for any compression, so the only value is NONE diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/StatFileRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/StatFileRequest.kt index 8091a16ae..50a5308cd 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/StatFileRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/sync/v2/StatFileRequest.kt @@ -34,7 +34,7 @@ import java.time.Instant @Features(Feature.STAT_V2) public class StatFileRequest( private val remotePath: String, - private val supportedFeatures: List + private val supportedFeatures: List, ) : ComplexRequest() { override suspend fun readElement(socket: Socket): FileEntryV2 { socket.writeSyncRequest(Const.Message.LSTAT_V2, remotePath) @@ -56,7 +56,7 @@ public class StatFileRequest( size = bytes.copyOfRange(40, 48).toULong(), atime = Instant.ofEpochSecond(bytes.copyOfRange(48, 56).toLong()), mtime = Instant.ofEpochSecond(bytes.copyOfRange(56, 64).toLong()), - ctime = Instant.ofEpochSecond(bytes.copyOfRange(64, 72).toLong()) + ctime = Instant.ofEpochSecond(bytes.copyOfRange(64, 72).toLong()), ) } } @@ -76,4 +76,3 @@ public class StatFileRequest( override fun serialize(): ByteArray = createBaseRequest("sync:") } - diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/InstrumentOptions.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/InstrumentOptions.kt index a371e53d1..3671164b5 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/InstrumentOptions.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/InstrumentOptions.kt @@ -64,7 +64,7 @@ public data class InstrumentOptions( public val log: Boolean? = null, public val emma: Boolean? = null, public val coverageFile: String? = null, - public val overrides: Map = mapOf() + public val overrides: Map = mapOf(), ) { override fun toString(): String = StringBuilder().apply { if (pkg.isNotEmpty()) append(" -e package " + pkg.joinToString(separator = ",")) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/InstrumentationSizeOption.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/InstrumentationSizeOption.kt index 66d2acee2..c0f4d79ff 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/InstrumentationSizeOption.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/InstrumentationSizeOption.kt @@ -19,5 +19,5 @@ package com.malinskiy.adam.request.testrunner public enum class InstrumentationSizeOption { SMALL, MEDIUM, - LARGE -} \ No newline at end of file + LARGE, +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestEvent.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestEvent.kt index 5776aa77d..03db48b64 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestEvent.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestEvent.kt @@ -27,5 +27,8 @@ public data class TestEnded(public val id: TestIdentifier, public val metrics: M public data class TestRunFailed(public val error: String) : TestEvent() public data class TestRunFailing(public val error: String, public val stackTrace: String) : TestEvent() public data class TestRunStopped(public val elapsedTimeMillis: Long) : TestEvent() -public data class TestRunEnded(public val elapsedTimeMillis: Long, public val metrics: Map) : TestEvent() +public data class TestRunEnded( + public val elapsedTimeMillis: Long, + public val metrics: Map, +) : TestEvent() public data class TestLogcat(public val id: TestIdentifier, public val log: String) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestIdentifier.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestIdentifier.kt index 37768beaf..a05d7762b 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestIdentifier.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestIdentifier.kt @@ -18,5 +18,5 @@ package com.malinskiy.adam.request.testrunner public data class TestIdentifier( public val className: String, - public val testName: String + public val testName: String, ) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestRunnerRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestRunnerRequest.kt index c2cbc03b2..8848b31ec 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestRunnerRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/TestRunnerRequest.kt @@ -59,7 +59,7 @@ public class TestRunnerRequest( private val outputLogPath: String? = null, private val protobuf: Boolean = false, private val dumpFile: File? = null, - socketIdleTimeout: Long? = Long.MAX_VALUE + socketIdleTimeout: Long? = Long.MAX_VALUE, ) : AsyncCompatShellCommandRequest>( cmd = StringBuilder().apply { append("am instrument -w -r") diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/SessionResultCode.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/SessionResultCode.kt index 1037409c5..32314ab33 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/SessionResultCode.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/SessionResultCode.kt @@ -18,5 +18,5 @@ package com.malinskiy.adam.request.testrunner.model public enum class SessionResultCode(public val value: Int) { FINISHED(-1), - ERROR(0) + ERROR(0), } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/Status.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/Status.kt index 9910de4d1..6cb1909b4 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/Status.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/Status.kt @@ -28,7 +28,8 @@ public enum class Status(public val value: Int) { FAILURE(-2), IGNORED(-3), ASSUMPTION_FAILURE(-4), - UNKNOWN(6666); + UNKNOWN(6666), + ; public fun isTerminal(): Boolean = value < 0 diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/StatusKey.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/StatusKey.kt index ed254e894..de69b8463 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/StatusKey.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/StatusKey.kt @@ -26,7 +26,8 @@ public enum class StatusKey(public val value: String) { STREAM("stream"), CURRENT("current"), ID("id"), - UNKNOWN(""); + UNKNOWN(""), + ; public companion object { public fun of(value: String?): StatusKey = when (value) { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/TestStatusAggregator.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/TestStatusAggregator.kt index bbab467e0..06967bd0b 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/TestStatusAggregator.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/TestStatusAggregator.kt @@ -21,5 +21,5 @@ import com.malinskiy.adam.Const public data class TestStatusAggregator( public var statusCode: Status, public val logcatBuilder: StringBuilder = StringBuilder(Const.MAX_PROTOBUF_LOGCAT_LENGTH), - public val metrics: MutableMap = mutableMapOf() + public val metrics: MutableMap = mutableMapOf(), ) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/TokenType.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/TokenType.kt index 7e63ec9c7..6e268d8cb 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/TokenType.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/model/TokenType.kt @@ -21,5 +21,5 @@ public enum class TokenType { INSTRUMENTATION_STATUS_CODE, INSTRUMENTATION_RESULT, INSTRUMENTATION_CODE, - INSTRUMENTATION_FAILED + INSTRUMENTATION_FAILED, } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformer.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformer.kt index b964efa1a..4d86f3f94 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformer.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformer.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Anton Malinskiy + * Copyright (C) 2021 Anton Malinskiy * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,8 +61,8 @@ public class InstrumentationResponseTransformer : ProgressiveResponseTransformer val tokenPosition = buffer.indexOfAny( listOf( TokenType.INSTRUMENTATION_STATUS_CODE.name, - TokenType.INSTRUMENTATION_CODE.name - ) + TokenType.INSTRUMENTATION_CODE.name, + ), ) if (tokenPosition == -1) { @@ -105,14 +105,17 @@ public class InstrumentationResponseTransformer : ProgressiveResponseTransformer last.startsWith(TokenType.INSTRUMENTATION_STATUS_CODE.name) -> { parseStatusCode(last, atom.subList(0, atom.size - 1)) } + last.startsWith(TokenType.INSTRUMENTATION_CODE.name) -> { finished = true parseInstrumentationCode(last, atom) } + last.startsWith(TokenType.INSTRUMENTATION_FAILED.name) -> { finished = true null } + else -> null } } @@ -150,6 +153,7 @@ public class InstrumentationResponseTransformer : ProgressiveResponseTransformer } testsExecuted += 1 } + Status.START -> { val className = parameters["class"] val testName = parameters["test"] @@ -157,9 +161,11 @@ public class InstrumentationResponseTransformer : ProgressiveResponseTransformer events.add(TestStarted(TestIdentifier(className, testName))) } } + Status.IN_PROGRESS -> { testMetrics.putAll(parameters.filterKeys { !KNOWN_KEYS.contains(it) }) } + Status.ERROR, Status.FAILURE -> { val className = parameters["class"] val testName = parameters["test"] @@ -177,6 +183,7 @@ public class InstrumentationResponseTransformer : ProgressiveResponseTransformer } testsExecuted += 1 } + Status.IGNORED -> { val className = parameters["class"] val testName = parameters["test"] @@ -188,6 +195,7 @@ public class InstrumentationResponseTransformer : ProgressiveResponseTransformer } testsExecuted += 1 } + Status.ASSUMPTION_FAILURE -> { val className = parameters["class"] val testName = parameters["test"] @@ -200,6 +208,7 @@ public class InstrumentationResponseTransformer : ProgressiveResponseTransformer } testsExecuted += 1 } + Status.UNKNOWN -> TODO() } @@ -217,7 +226,7 @@ public class InstrumentationResponseTransformer : ProgressiveResponseTransformer */ private fun parseInstrumentationCode( last: String, - atom: List + atom: List, ): List? { val value = last.substring(TokenType.INSTRUMENTATION_CODE.name.length + 1).trim() val code = value.toIntOrNull() @@ -238,6 +247,7 @@ public class InstrumentationResponseTransformer : ProgressiveResponseTransformer finishReported = true listOf(TestRunEnded(time, metrics)) } + else -> { finishReported = true var shortMessage: String? = null @@ -247,18 +257,23 @@ public class InstrumentationResponseTransformer : ProgressiveResponseTransformer line.startsWith("INSTRUMENTATION_RESULT: shortMsg=") -> { shortMessage = line.substring(33) } + line.startsWith("Time: ") -> { time = line.substring(6).toDoubleOrNull()?.times(1000)?.toLong() ?: 0L } } } - listOf(TestRunFailed(shortMessage ?: "Unexpected INSTRUMENTATION_CODE: $code"), TestRunEnded(time, emptyMap())) + listOf( + TestRunFailed(shortMessage ?: "Unexpected INSTRUMENTATION_CODE: $code"), + TestRunEnded(time, emptyMap()), + ) } } } public companion object { - public val KNOWN_KEYS: Set = setOf("test", "class", "stack", "numtests", "Error", "shortMsg", "stream", "current", "id") + public val KNOWN_KEYS: Set = + setOf("test", "class", "stack", "numtests", "Error", "shortMsg", "stream", "current", "id") } } @@ -276,4 +291,3 @@ private fun List.toMap(delimiter: String = "INSTRUMENTATION_STATUS: "): Pair(trimmed.substring(0, delimiterIndex), trimmed.substring(delimiterIndex + 1, trimmed.length)) }.toMap() } - diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/transform/DumpResponseTransformer.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/transform/DumpResponseTransformer.kt index 724e41efa..9fa94be38 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/transform/DumpResponseTransformer.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/transform/DumpResponseTransformer.kt @@ -37,4 +37,4 @@ public class DumpResponseTransformer( override fun transform(): T { return delegate.transform() } -} \ No newline at end of file +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/transform/StringResponseTransformer.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/transform/StringResponseTransformer.kt index b3a5a522e..56670e9d6 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/transform/StringResponseTransformer.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/transform/StringResponseTransformer.kt @@ -29,4 +29,4 @@ public class StringResponseTransformer : ResponseTransformer { override fun transform(): String { return builder.toString().trim() } -} \ No newline at end of file +} diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/BufferFactory.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/BufferFactory.kt index 0bedaa9e7..c10544be8 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/BufferFactory.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/BufferFactory.kt @@ -28,9 +28,12 @@ import java.nio.ByteOrder internal const val DEFAULT_BUFFER_SIZE = 4088 -public val AdamDefaultPool: ByteBufferPool = ByteBufferPool(poolSize = Const.DEFAULT_BUFFER_SIZE, bufferSize = DEFAULT_BUFFER_SIZE) -public val AdamMaxPacketPool: ByteBufferPool = ByteBufferPool(poolSize = Const.DEFAULT_BUFFER_SIZE, bufferSize = Const.MAX_PACKET_LENGTH) -public val AdamMaxFilePacketPool: ByteBufferPool = ByteBufferPool(poolSize = Const.DEFAULT_BUFFER_SIZE, bufferSize = Const.MAX_FILE_PACKET_LENGTH) +public val AdamDefaultPool: ByteBufferPool = + ByteBufferPool(poolSize = Const.DEFAULT_BUFFER_SIZE, bufferSize = DEFAULT_BUFFER_SIZE) +public val AdamMaxPacketPool: ByteBufferPool = + ByteBufferPool(poolSize = Const.DEFAULT_BUFFER_SIZE, bufferSize = Const.MAX_PACKET_LENGTH) +public val AdamMaxFilePacketPool: ByteBufferPool = + ByteBufferPool(poolSize = Const.DEFAULT_BUFFER_SIZE, bufferSize = Const.MAX_FILE_PACKET_LENGTH) public class ByteBufferPool(private val poolSize: Int, private val bufferSize: Int) { private val delegate: GenericObjectPool by lazy { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/SocketFactory.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/SocketFactory.kt index efe176d4d..97ba1446d 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/SocketFactory.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/SocketFactory.kt @@ -20,6 +20,10 @@ import java.io.Closeable import java.net.InetSocketAddress public interface SocketFactory : Closeable { - public suspend fun tcp(socketAddress: InetSocketAddress, connectTimeout: Long? = null, idleTimeout: Long? = null): Socket + public suspend fun tcp( + socketAddress: InetSocketAddress, + connectTimeout: Long? = null, + idleTimeout: Long? = null, + ): Socket override fun close() } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/SuspendCloseable.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/SuspendCloseable.kt index be22e98f5..6e0372579 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/SuspendCloseable.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/SuspendCloseable.kt @@ -38,7 +38,7 @@ public suspend inline fun C.use(crossinline block: sus try { Throwable::class.java.getMethod("addSuppressed", Throwable::class.java).invoke(this, second) } catch (t: Throwable) { - //Nothing to do + // Nothing to do } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/TransportResponse.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/TransportResponse.kt index 7b4fdbccb..4ade9d045 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/TransportResponse.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/TransportResponse.kt @@ -18,5 +18,5 @@ package com.malinskiy.adam.transport public class TransportResponse( public val okay: Boolean, - public val message: String? -) \ No newline at end of file + public val message: String?, +) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocket.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocket.kt index 1cb0eea2b..efe1982b8 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocket.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocket.kt @@ -45,7 +45,11 @@ import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicReference import kotlin.coroutines.CoroutineContext -public class VertxSocket(private val socketAddress: SocketAddress, private val options: NetClientOptions) : CoroutineVerticle(), Socket { +public class VertxSocket( + private val socketAddress: SocketAddress, + private val options: NetClientOptions, +) : CoroutineVerticle(), Socket { + public var id: String? = null public var netClient: NetClient? = null private lateinit var socket: NetSocketImpl @@ -214,7 +218,7 @@ public fun ReadStream.toChannel(context: Context): ReceiveChannel { val ret = ChannelReadStream( stream = this, channel = Channel(16), - context = context + context = context, ) ret.subscribe() this.fetch(1) @@ -224,7 +228,7 @@ public fun ReadStream.toChannel(context: Context): ReceiveChannel { private class ChannelReadStream( val stream: ReadStream, val channel: Channel, - context: Context + context: Context, ) : Channel by channel, CoroutineScope { private val logger = AdamLogging.logger { } @@ -256,7 +260,7 @@ private enum class State { SYN_SENT, ESTABLISHED, CLOSING, - CLOSE_WAIT + CLOSE_WAIT, } private fun AtomicBoolean.flip(expected: Boolean, error: () -> String) { diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocketFactory.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocketFactory.kt index 3d6df8e7b..c3c913c46 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocketFactory.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VertxSocketFactory.kt @@ -27,7 +27,7 @@ import java.util.concurrent.atomic.AtomicBoolean public class VertxSocketFactory( private val connectTimeout: Long = 10_000, - private val idleTimeout: Long = 30_000 + private val idleTimeout: Long = 30_000, ) : SocketFactory { private val vertx by lazy { Vertx.vertx().also { initialized.set(true) } @@ -35,10 +35,13 @@ public class VertxSocketFactory( private val initialized = AtomicBoolean(false) override suspend fun tcp(socketAddress: InetSocketAddress, connectTimeout: Long?, idleTimeout: Long?): Socket { - val vertxSocket = VertxSocket(SocketAddress.inetSocketAddress(socketAddress), NetClientOptions().apply { - setConnectTimeout((connectTimeout ?: this@VertxSocketFactory.connectTimeout).toTimeoutInt()) - setIdleTimeout((idleTimeout ?: this@VertxSocketFactory.idleTimeout).toTimeoutInt()) - }) + val vertxSocket = VertxSocket( + SocketAddress.inetSocketAddress(socketAddress), + NetClientOptions().apply { + setConnectTimeout((connectTimeout ?: this@VertxSocketFactory.connectTimeout).toTimeoutInt()) + setIdleTimeout((idleTimeout ?: this@VertxSocketFactory.idleTimeout).toTimeoutInt()) + }, + ) val id = vertx.deployVerticle(vertxSocket).coAwait() vertxSocket.id = id return vertxSocket @@ -52,7 +55,10 @@ public class VertxSocketFactory( private fun Long.toTimeoutInt(): Int { val toInt = toInt() - return if (toInt < 0) Int.MAX_VALUE - else toInt + return if (toInt < 0) { + Int.MAX_VALUE + } else { + toInt + } } } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/AndroidDebugBridgeClientTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/AndroidDebugBridgeClientTest.kt index c74d339c3..4c995881d 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/AndroidDebugBridgeClientTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/AndroidDebugBridgeClientTest.kt @@ -93,16 +93,19 @@ class AndroidDebugBridgeClientTest { @Test(expected = RequestValidationException::class) fun testRequestValidation() { runBlocking { - client.execute(object : ComplexRequest() { - override fun validate() = ValidationResponse(false, "Fake") - override suspend fun readElement(socket: Socket): String { - TODO("Not yet implemented") - } + client.execute( + object : ComplexRequest() { + override fun validate() = ValidationResponse(false, "Fake") + override suspend fun readElement(socket: Socket): String { + TODO("Not yet implemented") + } - override fun serialize(): ByteArray { - TODO("Not yet implemented") - } - }, serial = "serial") + override fun serialize(): ByteArray { + TODO("Not yet implemented") + } + }, + serial = "serial", + ) } } } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/extension/ByteArrayExtensions.kt b/adam/src/test/kotlin/com/malinskiy/adam/extension/ByteArrayExtensions.kt index 592258b5f..e1926d4c9 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/extension/ByteArrayExtensions.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/extension/ByteArrayExtensions.kt @@ -18,4 +18,4 @@ package com.malinskiy.adam.extension import com.malinskiy.adam.Const -fun ByteArray.toRequestString() = String(this, Const.DEFAULT_TRANSPORT_ENCODING) \ No newline at end of file +fun ByteArray.toRequestString() = String(this, Const.DEFAULT_TRANSPORT_ENCODING) diff --git a/adam/src/test/kotlin/com/malinskiy/adam/integration/AdbBinaryIntegrationTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/integration/AdbBinaryIntegrationTest.kt index 1a4c2c619..127551d62 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/integration/AdbBinaryIntegrationTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/integration/AdbBinaryIntegrationTest.kt @@ -39,6 +39,5 @@ class AdbBinaryIntegrationTest { startAdbInteractor.execute(serverPort = customServerPort) stopAdbInteractor.execute(serverPort = customServerPort) } - } -} \ No newline at end of file +} diff --git a/adam/src/test/kotlin/com/malinskiy/adam/interactor/DiscoverAdbSocketInteractorTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/interactor/DiscoverAdbSocketInteractorTest.kt index 17df7d504..0c1fa36c9 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/interactor/DiscoverAdbSocketInteractorTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/interactor/DiscoverAdbSocketInteractorTest.kt @@ -37,4 +37,4 @@ class DiscoverAdbSocketInteractorTest { assertThat(execute).isEqualTo(1234) } -} \ No newline at end of file +} diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/AsyncShellCommandRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/AsyncShellCommandRequestTest.kt index d2a420cb9..fa7d0d41d 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/AsyncShellCommandRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/AsyncShellCommandRequestTest.kt @@ -28,4 +28,4 @@ class AsyncShellCommandRequestTest { assertThat(String(ChanneledShellCommandRequest("test").serialize(), Const.DEFAULT_TRANSPORT_ENCODING)) .isEqualTo("000Ashell:test") } -} \ No newline at end of file +} diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/TargetTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/TargetTest.kt index d230ff60d..dbd677ea2 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/TargetTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/TargetTest.kt @@ -27,6 +27,5 @@ class TargetTest { assertThat(UsbTarget.serialize()).isEqualTo("host-usb:") assertThat(LocalTarget.serialize()).isEqualTo("host-local:") - } -} \ No newline at end of file +} diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/abb/AbbExecRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/abb/AbbExecRequestTest.kt index 15fe7d4b0..42e4beb1e 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/abb/AbbExecRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/abb/AbbExecRequestTest.kt @@ -38,7 +38,9 @@ class AbbExecRequestTest { @Test fun testSerialize() { - assertThat(AbbExecRequest(listOf("cmd", "package", "install"), listOf(Feature.ABB_EXEC)).serialize().toRequestString()) + assertThat( + AbbExecRequest(listOf("cmd", "package", "install"), listOf(Feature.ABB_EXEC)).serialize().toRequestString(), + ) .isEqualTo("001Cabb_exec:cmd\u0000package\u0000install") } @@ -59,7 +61,7 @@ class AbbExecRequestTest { runBlocking { StubSocket("cafebabe".toByteArray(Const.DEFAULT_TRANSPORT_ENCODING)).use { socket -> assertThat( - AbbExecRequest(listOf(), supportedFeatures = emptyList()).readElement(socket) + AbbExecRequest(listOf(), supportedFeatures = emptyList()).readElement(socket), ).isEqualTo("cafebabe") } } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/device/FetchDeviceFeaturesRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/device/FetchDeviceFeaturesRequestTest.kt index 2c24220fc..27aefd964 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/device/FetchDeviceFeaturesRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/device/FetchDeviceFeaturesRequestTest.kt @@ -34,8 +34,8 @@ class FetchDeviceFeaturesRequestTest { assertThat( String( fetchDeviceFeaturesRequest.serialize(), - Const.DEFAULT_TRANSPORT_ENCODING - ) + Const.DEFAULT_TRANSPORT_ENCODING, + ), ).isEqualTo("001Dhost-serial:cafebabe:features") } @@ -45,7 +45,7 @@ class FetchDeviceFeaturesRequestTest { runBlocking { StubSocket( content = "0054fixed_push_symlink_timestamp,apex,fixed_push_mkdir,stat_v2,abb_exec,cmd,abb,shell_v2" - .toByteArray(Const.DEFAULT_TRANSPORT_ENCODING) + .toByteArray(Const.DEFAULT_TRANSPORT_ENCODING), ).use { socket -> val features = fetchDeviceFeaturesRequest.readElement(socket) @@ -57,7 +57,7 @@ class FetchDeviceFeaturesRequestTest { Feature.ABB_EXEC, Feature.CMD, Feature.ABB, - Feature.SHELL_V2 + Feature.SHELL_V2, ) } } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/device/ListDevicesRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/device/ListDevicesRequestTest.kt index 58555859a..ab7bfd941 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/device/ListDevicesRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/device/ListDevicesRequestTest.kt @@ -48,7 +48,7 @@ class ListDevicesRequestTest { "emulator-5570" to "authorizing", "emulator-5572" to "connecting", "emulator-5574" to "wtf", - ) + ), ) } @@ -64,7 +64,7 @@ class ListDevicesRequestTest { Device("emulator-5568", DeviceState.UNAUTHORIZED), Device("emulator-5570", DeviceState.AUTHORIZING), Device("emulator-5572", DeviceState.CONNECTING), - Device("emulator-5574", DeviceState.UNKNOWN) + Device("emulator-5574", DeviceState.UNKNOWN), ) } } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/ListPortForwardsRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/ListPortForwardsRequestTest.kt index e815a7dea..16482ba62 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/ListPortForwardsRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/ListPortForwardsRequestTest.kt @@ -46,8 +46,8 @@ class ListPortForwardsRequestTest { xx local:/tmp/socket localfilesystem:namedsocket xx local:/tmp/socket dev:/dev/chardev xx local:/tmp/socket jdwp:1001 - - """.trimIndent() + + """.trimIndent(), ) input.discard() @@ -58,9 +58,13 @@ class ListPortForwardsRequestTest { PortForwardingRule("xx", LocalTcpPortSpec(80), RemoteTcpPortSpec(80)), PortForwardingRule("xx", LocalUnixSocketPortSpec("/tmp/socket"), RemoteAbstractPortSpec("namedsocket")), PortForwardingRule("xx", LocalUnixSocketPortSpec("/tmp/socket"), RemoteReservedPortSpec("namedsocket")), - PortForwardingRule("xx", LocalUnixSocketPortSpec("/tmp/socket"), RemoteFilesystemPortSpec("namedsocket")), + PortForwardingRule( + "xx", + LocalUnixSocketPortSpec("/tmp/socket"), + RemoteFilesystemPortSpec("namedsocket"), + ), PortForwardingRule("xx", LocalUnixSocketPortSpec("/tmp/socket"), RemoteDevPortSpec("/dev/chardev")), - PortForwardingRule("xx", LocalUnixSocketPortSpec("/tmp/socket"), JDWPPortSpec(1001)) + PortForwardingRule("xx", LocalUnixSocketPortSpec("/tmp/socket"), JDWPPortSpec(1001)), ) assertThat(output.first().serial).isEqualTo("xx") diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/LocalPortSpecTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/LocalPortSpecTest.kt index eb16d3f27..d8f8dadd8 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/LocalPortSpecTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/LocalPortSpecTest.kt @@ -21,7 +21,6 @@ import assertk.assertions.isEqualTo import com.malinskiy.adam.exception.UnsupportedForwardingSpecException import org.junit.Test - class LocalPortSpecTest { @Test(expected = UnsupportedForwardingSpecException::class) fun testUnsupported() { @@ -32,4 +31,4 @@ class LocalPortSpecTest { fun testLocalUnixSocketPortSpec() { assertThat(LocalUnixSocketPortSpec("path").toSpec()).isEqualTo("local:path") } -} \ No newline at end of file +} diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/PortForwardRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/PortForwardRequestTest.kt index cfd0926a3..0b3391bd7 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/PortForwardRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/PortForwardRequestTest.kt @@ -46,7 +46,7 @@ class PortForwardRequestTest { LocalTcpPortSpec(80), RemoteTcpPortSpec(80), "emulator-5554", - mode = PortForwardingMode.NO_REBIND + mode = PortForwardingMode.NO_REBIND, ).serialize() assertThat(String(bytes, Const.DEFAULT_TRANSPORT_ENCODING)) diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/RemotePortSpecTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/RemotePortSpecTest.kt index 4bbd5cc9d..bfc3aff41 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/RemotePortSpecTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/RemotePortSpecTest.kt @@ -46,4 +46,4 @@ class RemotePortSpecTest { fun testJDWPPortSpec() { assertThat(JDWPPortSpec(1).toSpec()).isEqualTo("jdwp:1") } -} \ No newline at end of file +} diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/RemovePortForwardRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/RemovePortForwardRequestTest.kt index 6d6f64a7c..79937d4b9 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/RemovePortForwardRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/forwarding/RemovePortForwardRequestTest.kt @@ -34,8 +34,12 @@ class RemovePortForwardRequestTest { @Test fun testDummy() { runBlocking { - assertThat(RemovePortForwardRequest(serial = "serial", local = LocalTcpPortSpec()).process(ByteArray(1), 0, 1)).isEqualTo(Unit) - assertThat(RemovePortForwardRequest(serial = "serial", local = LocalTcpPortSpec()).transform()).isEqualTo(Unit) + assertThat( + RemovePortForwardRequest(serial = "serial", local = LocalTcpPortSpec()).process(ByteArray(1), 0, 1), + ).isEqualTo(Unit) + assertThat( + RemovePortForwardRequest(serial = "serial", local = LocalTcpPortSpec()).transform(), + ).isEqualTo(Unit) } } } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequestTest.kt index 3f7d47a43..a47861b68 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequestTest.kt @@ -34,7 +34,6 @@ import java.io.File import javax.imageio.ImageIO import kotlin.system.measureTimeMillis - class ScreenCaptureRequestTest { @Rule @JvmField @@ -287,7 +286,7 @@ class ScreenCaptureRequestTest { expectCmd { "host:transport:serial" }.accept() expectCmd { "framebuffer:" }.accept() - //Unsupported version + // Unsupported version output.writeIntLittleEndian(99) } @@ -297,7 +296,7 @@ class ScreenCaptureRequestTest { private fun compare( expected: BufferedImage, - actual: BufferedImage + actual: BufferedImage, ): ImageComparisonResult { val imageComparison = ImageComparison(expected, actual) val comparisonResult = imageComparison.compareImages() diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/framebuffer/screencapture/BufferedImageScreenCaptureAdapterTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/framebuffer/screencapture/BufferedImageScreenCaptureAdapterTest.kt index ecb3466c6..ee235ff64 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/framebuffer/screencapture/BufferedImageScreenCaptureAdapterTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/framebuffer/screencapture/BufferedImageScreenCaptureAdapterTest.kt @@ -43,7 +43,7 @@ class BufferedImageScreenCaptureAdapterTest { 0, 0, null, - socket + socket, ) } } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/logcat/AsyncLogcatRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/logcat/AsyncLogcatRequestTest.kt index dbac53a24..10b924dd0 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/logcat/AsyncLogcatRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/logcat/AsyncLogcatRequestTest.kt @@ -26,7 +26,7 @@ class AsyncLogcatRequestTest { @Test fun testModeArguments() { val cmd = ChanneledLogcatRequest( - modes = listOf(LogcatReadMode.long, LogcatReadMode.epoch) + modes = listOf(LogcatReadMode.long, LogcatReadMode.epoch), ).serialize() assertThat(String(cmd, Const.DEFAULT_TRANSPORT_ENCODING)) @@ -36,7 +36,7 @@ class AsyncLogcatRequestTest { @Test fun testBuffers() { val cmd = ChanneledLogcatRequest( - buffers = listOf(LogcatBuffer.crash, LogcatBuffer.radio) + buffers = listOf(LogcatBuffer.crash, LogcatBuffer.radio), ).serialize() assertThat(String(cmd, Const.DEFAULT_TRANSPORT_ENCODING)) @@ -85,9 +85,9 @@ class AsyncLogcatRequestTest { SupressAll, LogcatFilterSpec( "SOMETAG", - LogcatVerbosityLevel.E - ) - ) + LogcatVerbosityLevel.E, + ), + ), ).serialize() assertThat(String(cmd, Const.DEFAULT_TRANSPORT_ENCODING)) diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/mdns/ListMdnsServicesRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/mdns/ListMdnsServicesRequestTest.kt index 63e6dcd63..9ca38c3fc 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/mdns/ListMdnsServicesRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/mdns/ListMdnsServicesRequestTest.kt @@ -35,7 +35,9 @@ class ListMdnsServicesRequestTest { @Test fun testReturnsContent() { runBlocking { - val response = "0027adb-serial\t_adb._tcp.\t192.168.1.2:9999\n".toByteArray(Const.DEFAULT_TRANSPORT_ENCODING) + val response = "0027adb-serial\t_adb._tcp.\t192.168.1.2:9999\n".toByteArray( + Const.DEFAULT_TRANSPORT_ENCODING, + ) StubSocket(response).use { socket -> val services = ListMdnsServicesRequest().readElement(socket) @@ -43,8 +45,8 @@ class ListMdnsServicesRequestTest { MdnsService( name = "adb-serial", serviceType = "_adb._tcp.", - url = "192.168.1.2:9999" - ) + url = "192.168.1.2:9999", + ), ) assertThat(services.first().name).isEqualTo("adb-serial") diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/mdns/MdnsCheckRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/mdns/MdnsCheckRequestTest.kt index 884dd20de..2e1d32156 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/mdns/MdnsCheckRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/mdns/MdnsCheckRequestTest.kt @@ -51,7 +51,6 @@ class MdnsCheckRequestTest { StubSocket(response).use { socket -> val value = MdnsCheckRequest().readElement(socket) assertThat(value).isEqualTo(MdnsStatus(false, null)) - } } } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/misc/DisconnectDeviceRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/misc/DisconnectDeviceRequestTest.kt index 858e6dfe7..c89f84256 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/misc/DisconnectDeviceRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/misc/DisconnectDeviceRequestTest.kt @@ -62,4 +62,3 @@ class DisconnectDeviceRequestTest { } } } - diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/misc/FetchHostFeaturesRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/misc/FetchHostFeaturesRequestTest.kt index ded64dca1..6f20836b8 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/misc/FetchHostFeaturesRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/misc/FetchHostFeaturesRequestTest.kt @@ -50,7 +50,7 @@ class FetchHostFeaturesRequestTest { Feature.ABB_EXEC, Feature.CMD, Feature.ABB, - Feature.SHELL_V2 + Feature.SHELL_V2, ) } } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/misc/RebootRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/misc/RebootRequestTest.kt index b2db45c0b..6f15f0f2b 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/misc/RebootRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/misc/RebootRequestTest.kt @@ -53,7 +53,9 @@ class RebootRequestTest { @Test fun testSideloadAutoReboot() { - val actual = RebootRequest(RebootMode.SIDELOAD_AUTO_REBOOT).serialize().toString(Const.DEFAULT_TRANSPORT_ENCODING) + val actual = RebootRequest( + RebootMode.SIDELOAD_AUTO_REBOOT, + ).serialize().toString(Const.DEFAULT_TRANSPORT_ENCODING) assertThat(actual) .isEqualTo("001Breboot:sideload-auto-reboot") } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/InstallRemotePackageRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/InstallRemotePackageRequestTest.kt index 5064067dc..ebb7564b2 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/InstallRemotePackageRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/InstallRemotePackageRequestTest.kt @@ -50,8 +50,14 @@ class InstallRemotePackageRequestTest { @Test fun testValidation() { - assertThat(InstallRemotePackageRequest("/data/local/tmp/file.apk", true, emptyList()).validate().success).isTrue() - assertThat(InstallRemotePackageRequest("/data/local/tmp/file.apex", true, emptyList()).validate().success).isFalse() - assertThat(InstallRemotePackageRequest("/data/local/tmp/file.bin", true, emptyList()).validate().success).isFalse() + assertThat( + InstallRemotePackageRequest("/data/local/tmp/file.apk", true, emptyList()).validate().success, + ).isTrue() + assertThat( + InstallRemotePackageRequest("/data/local/tmp/file.apex", true, emptyList()).validate().success, + ).isFalse() + assertThat( + InstallRemotePackageRequest("/data/local/tmp/file.bin", true, emptyList()).validate().success, + ).isFalse() } } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/AddSessionRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/AddSessionRequestTest.kt index 32c210d13..292cda076 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/AddSessionRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/AddSessionRequestTest.kt @@ -33,10 +33,10 @@ class AddSessionRequestTest { val request = AddSessionRequest( childSessions = listOf("child-session-1", "child-session-2"), parentSession = "parent-session-1", - supportedFeatures = listOf(Feature.CMD) + supportedFeatures = listOf(Feature.CMD), ) assertThat( - request.serialize().toRequestString() + request.serialize().toRequestString(), ).isEqualTo("0055exec:cmd package install-add-session parent-session-1 child-session-1 child-session-2") } @@ -46,11 +46,13 @@ class AddSessionRequestTest { AddSessionRequest( childSessions = listOf("child-session-1", "child-session-2"), parentSession = "parent-session-1", - supportedFeatures = listOf(Feature.CMD, Feature.ABB_EXEC) + supportedFeatures = listOf(Feature.CMD, Feature.ABB_EXEC), ) assertThat( - request.serialize().toRequestString() - ).isEqualTo("0055abb_exec:package\u0000install-add-session\u0000parent-session-1\u0000child-session-1\u0000child-session-2") + request.serialize().toRequestString(), + ).isEqualTo( + "0055abb_exec:package\u0000install-add-session\u0000parent-session-1\u0000child-session-1\u0000child-session-2", + ) } @Test @@ -59,7 +61,7 @@ class AddSessionRequestTest { AddSessionRequest( childSessions = listOf("child-session-1", "child-session-2"), parentSession = "parent-session-1", - supportedFeatures = listOf(Feature.CMD) + supportedFeatures = listOf(Feature.CMD), ) val response = "Success".toByteArray(Const.DEFAULT_TRANSPORT_ENCODING) @@ -76,7 +78,7 @@ class AddSessionRequestTest { AddSessionRequest( childSessions = listOf("child-session-1", "child-session-2"), parentSession = "parent-session-1", - supportedFeatures = listOf(Feature.CMD) + supportedFeatures = listOf(Feature.CMD), ) val response = "Failure".toByteArray(Const.DEFAULT_TRANSPORT_ENCODING) diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/CreateIndividualPackageSessionRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/CreateIndividualPackageSessionRequestTest.kt index 2627143f5..80b0b3f2e 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/CreateIndividualPackageSessionRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/CreateIndividualPackageSessionRequestTest.kt @@ -50,7 +50,7 @@ class CreateIndividualPackageSessionRequestTest { supportedFeatures = listOf(Feature.CMD, Feature.ABB_EXEC), pkg = pkg, pkgList = listOf(pkg), - reinstall = false + reinstall = false, ) assertThat(request.serialize().toRequestString()) .isEqualTo("001Fabb_exec:package\u0000install-create") @@ -63,7 +63,7 @@ class CreateIndividualPackageSessionRequestTest { supportedFeatures = listOf(), pkg = pkg, pkgList = listOf(pkg), - reinstall = false + reinstall = false, ) assertThat(request.serialize().toRequestString()) .isEqualTo("0016exec:pm install-create") @@ -77,7 +77,7 @@ class CreateIndividualPackageSessionRequestTest { pkg = pkg, extraArgs = listOf("-g"), pkgList = listOf(pkg), - reinstall = true + reinstall = true, ) assertThat(request.serialize().toRequestString()) .isEqualTo("0027exec:cmd package install-create '-g' -r") @@ -91,7 +91,7 @@ class CreateIndividualPackageSessionRequestTest { pkg = pkg, extraArgs = listOf("-g"), pkgList = listOf(pkg), - reinstall = true + reinstall = true, ) assertThat(request.serialize().toRequestString()) .isEqualTo("0037exec:cmd package install-create '-g' -r --staged --apex") @@ -139,7 +139,7 @@ class CreateIndividualPackageSessionRequestTest { pkg = pkg, extraArgs = emptyList(), pkgList = listOf(pkg), - reinstall = false + reinstall = false, ) return request } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/CreateMultiPackageSessionRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/CreateMultiPackageSessionRequestTest.kt index 679104d48..d208c7cec 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/CreateMultiPackageSessionRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/CreateMultiPackageSessionRequestTest.kt @@ -28,7 +28,6 @@ import com.malinskiy.adam.request.Feature import com.malinskiy.adam.request.ValidationResponse import com.malinskiy.adam.server.stub.StubSocket import com.malinskiy.adam.transport.use - import kotlinx.coroutines.runBlocking import org.junit.Rule import org.junit.Test @@ -54,7 +53,7 @@ class CreateMultiPackageSessionRequestTest { supportedFeatures = listOf(Feature.CMD, Feature.ABB_EXEC), extraArgs = emptyList(), pkgList = listOf(pkg), - reinstall = false + reinstall = false, ) assertThat(request.serialize().toRequestString()) .isEqualTo("002Fabb_exec:package\u0000install-create\u0000--multi-package") @@ -67,7 +66,7 @@ class CreateMultiPackageSessionRequestTest { supportedFeatures = listOf(Feature.CMD), extraArgs = listOf("-g"), pkgList = listOf(pkg), - reinstall = true + reinstall = true, ) assertThat(request.serialize().toRequestString()) .isEqualTo("0037exec:cmd package install-create --multi-package '-g' -r") @@ -80,7 +79,7 @@ class CreateMultiPackageSessionRequestTest { supportedFeatures = listOf(Feature.CMD), extraArgs = listOf("-g"), pkgList = listOf(pkg), - reinstall = true + reinstall = true, ) assertThat(request.serialize().toRequestString()) .isEqualTo("0040exec:cmd package install-create --multi-package '-g' -r --staged") @@ -88,12 +87,13 @@ class CreateMultiPackageSessionRequestTest { @Test fun serializeApkSplit() { - val pkg = ApkSplitInstallationPackage(listOf(temp.newFileWithExtension("apex"), temp.newFileWithExtension("apex"))) + val pkg = + ApkSplitInstallationPackage(listOf(temp.newFileWithExtension("apex"), temp.newFileWithExtension("apex"))) val request = CreateMultiPackageSessionRequest( supportedFeatures = listOf(Feature.CMD), extraArgs = listOf("-g"), pkgList = listOf(pkg), - reinstall = true + reinstall = true, ) assertThat(request.serialize().toRequestString()) .isEqualTo("0040exec:cmd package install-create --multi-package '-g' -r --staged") @@ -146,7 +146,7 @@ class CreateMultiPackageSessionRequestTest { supportedFeatures = listOf(Feature.CMD), extraArgs = emptyList(), pkgList = listOf(pkg), - reinstall = false + reinstall = false, ) assertThat(request.validate().success).isFalse() } @@ -157,7 +157,7 @@ class CreateMultiPackageSessionRequestTest { val request = CreateMultiPackageSessionRequest( supportedFeatures = listOf(Feature.CMD), pkgList = listOf(pkg), - reinstall = false + reinstall = false, ) assertThat(request.validate().success).isFalse() } @@ -169,7 +169,7 @@ class CreateMultiPackageSessionRequestTest { supportedFeatures = listOf(Feature.CMD), extraArgs = emptyList(), pkgList = listOf(pkg), - reinstall = false + reinstall = false, ) assertThat(request.validate().success).isFalse() } @@ -181,7 +181,7 @@ class CreateMultiPackageSessionRequestTest { supportedFeatures = listOf(), extraArgs = emptyList(), pkgList = listOf(pkg), - reinstall = false + reinstall = false, ) assertThat(request.validate().success).isFalse() @@ -189,7 +189,7 @@ class CreateMultiPackageSessionRequestTest { supportedFeatures = listOf(Feature.ABB_EXEC), extraArgs = emptyList(), pkgList = listOf(pkg), - reinstall = false + reinstall = false, ) assertThat(request.validate().success).isTrue() @@ -197,7 +197,7 @@ class CreateMultiPackageSessionRequestTest { supportedFeatures = listOf(Feature.CMD), extraArgs = emptyList(), pkgList = listOf(pkg), - reinstall = false + reinstall = false, ) assertThat(request.validate().success).isTrue() } @@ -209,31 +209,35 @@ class CreateMultiPackageSessionRequestTest { supportedFeatures = listOf(Feature.CMD), extraArgs = emptyList(), pkgList = listOf(pkg), - reinstall = false + reinstall = false, ) assertThat(request.validate().success).isFalse() } @Test fun testValidationApkSplit() { - val pkg = ApkSplitInstallationPackage(listOf(temp.newFileWithExtension("apk"), temp.newFileWithExtension("apk"))) + val pkg = + ApkSplitInstallationPackage(listOf(temp.newFileWithExtension("apk"), temp.newFileWithExtension("apk"))) var request = CreateMultiPackageSessionRequest( supportedFeatures = listOf(Feature.CMD), extraArgs = emptyList(), pkgList = listOf(pkg), - reinstall = false + reinstall = false, ) assertThat(request.validate().success).isTrue() } @Test fun testValidationFailureApkSplit() { - val pkg = ApkSplitInstallationPackage(listOf(temp.newFileWithExtension("apk"), kotlin.io.path.createTempFile(suffix = ".app").toFile())) + val pkg = + ApkSplitInstallationPackage( + listOf(temp.newFileWithExtension("apk"), kotlin.io.path.createTempFile(suffix = ".app").toFile()), + ) var request = CreateMultiPackageSessionRequest( supportedFeatures = listOf(Feature.CMD), extraArgs = emptyList(), pkgList = listOf(pkg), - reinstall = false + reinstall = false, ) assertThat(request.validate().success).isFalse() } @@ -244,7 +248,7 @@ class CreateMultiPackageSessionRequestTest { supportedFeatures = listOf(Feature.CMD), extraArgs = emptyList(), pkgList = listOf(pkg), - reinstall = false + reinstall = false, ) return request } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/InstallCommitRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/InstallCommitRequestTest.kt index 8004697ee..8dc508d54 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/InstallCommitRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/InstallCommitRequestTest.kt @@ -39,7 +39,7 @@ class InstallCommitRequestTest { fun serializeAbb() { val request = InstallCommitRequest( supportedFeatures = listOf(Feature.CMD, Feature.ABB_EXEC), - parentSession = "parent-session-id" + parentSession = "parent-session-id", ) assertThat(request.serialize().toRequestString()) .isEqualTo("0031abb_exec:package\u0000install-commit\u0000parent-session-id") @@ -50,7 +50,7 @@ class InstallCommitRequestTest { val request = InstallCommitRequest( supportedFeatures = listOf(Feature.CMD, Feature.ABB_EXEC), parentSession = "parent-session-id", - abandon = true + abandon = true, ) assertThat(request.serialize().toRequestString()) .isEqualTo("0032abb_exec:package\u0000install-abandon\u0000parent-session-id") @@ -84,8 +84,8 @@ class InstallCommitRequestTest { InstallCommitRequest( supportedFeatures = listOf(), parentSession = "parent-session-id", - abandon = false - ).serialize().toRequestString() + abandon = false, + ).serialize().toRequestString(), ).isEqualTo("0028exec:pm install-commit parent-session-id") } @@ -93,7 +93,7 @@ class InstallCommitRequestTest { val request = InstallCommitRequest( supportedFeatures = listOf(Feature.CMD), parentSession = "parent-session-id", - abandon = false + abandon = false, ) return request } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/WriteIndividualPackageRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/WriteIndividualPackageRequestTest.kt index 717008c65..312f22755 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/WriteIndividualPackageRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/pkg/multi/WriteIndividualPackageRequestTest.kt @@ -51,10 +51,12 @@ class WriteIndividualPackageRequestTest { val request = WriteIndividualPackageRequest( supportedFeatures = listOf(Feature.CMD, Feature.ABB_EXEC), file = File(WriteIndividualPackageRequestTest::class.java.getResource("/fixture/sample-fake.apk").file), - session = "session-id" + session = "session-id", ) assertThat(request.serialize().toRequestString()) - .isEqualTo("0042abb_exec:package\u0000install-write\u0000-S\u0000614\u0000session-id\u0000sample-fake.apk\u0000-") + .isEqualTo( + "0042abb_exec:package\u0000install-write\u0000-S\u0000614\u0000session-id\u0000sample-fake.apk\u0000-", + ) } @Test @@ -62,7 +64,7 @@ class WriteIndividualPackageRequestTest { val request = WriteIndividualPackageRequest( supportedFeatures = emptyList(), file = File(WriteIndividualPackageRequestTest::class.java.getResource("/fixture/sample-fake.apk").file), - session = "session-id" + session = "session-id", ) assertThat(request.serialize().toRequestString()) .isEqualTo("0039exec:pm install-write -S 614 session-id sample-fake.apk -") @@ -75,7 +77,7 @@ class WriteIndividualPackageRequestTest { val request = WriteIndividualPackageRequest( supportedFeatures = listOf(Feature.CMD), file = fixture, - session = "session-id" + session = "session-id", ) val response = "Success".toByteArray(Const.DEFAULT_TRANSPORT_ENCODING) val actual = temp.newFileWithExtension("apk") @@ -97,7 +99,7 @@ class WriteIndividualPackageRequestTest { val request = WriteIndividualPackageRequest( supportedFeatures = listOf(Feature.CMD), file = fixture, - session = "session-id" + session = "session-id", ) val response = "Failure".toByteArray(Const.DEFAULT_TRANSPORT_ENCODING) val actual = temp.newFileWithExtension("apk") @@ -115,7 +117,7 @@ class WriteIndividualPackageRequestTest { val request = WriteIndividualPackageRequest( supportedFeatures = listOf(Feature.CMD), file = File(WriteIndividualPackageRequestTest::class.java.getResource("/fixture/sample-fake.apk").file), - session = "session-id" + session = "session-id", ) return request } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/reverse/ListReversePortForwardsRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/reverse/ListReversePortForwardsRequestTest.kt index 65d8c6582..1abc1f159 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/reverse/ListReversePortForwardsRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/reverse/ListReversePortForwardsRequestTest.kt @@ -50,17 +50,29 @@ class ListReversePortForwardsRequestTest { xx localabstract:namedsocket local:/tmp/socket xx localreserved:namedsocket local:/tmp/socket xx localfilesystem:namedsocket local:/tmp/socket - - """.trimIndent() + + """.trimIndent(), ) } val output = client.execute(ListReversePortForwardsRequest(), serial = "xx") assertThat(output).containsExactly( ReversePortForwardingRule("xx", RemoteTcpPortSpec(80), LocalTcpPortSpec(80)), - ReversePortForwardingRule("xx", RemoteAbstractPortSpec("namedsocket"), LocalUnixSocketPortSpec("/tmp/socket")), - ReversePortForwardingRule("xx", RemoteReservedPortSpec("namedsocket"), LocalUnixSocketPortSpec("/tmp/socket")), - ReversePortForwardingRule("xx", RemoteFilesystemPortSpec("namedsocket"), LocalUnixSocketPortSpec("/tmp/socket")) + ReversePortForwardingRule( + "xx", + RemoteAbstractPortSpec("namedsocket"), + LocalUnixSocketPortSpec("/tmp/socket"), + ), + ReversePortForwardingRule( + "xx", + RemoteReservedPortSpec("namedsocket"), + LocalUnixSocketPortSpec("/tmp/socket"), + ), + ReversePortForwardingRule( + "xx", + RemoteFilesystemPortSpec("namedsocket"), + LocalUnixSocketPortSpec("/tmp/socket"), + ), ) assertThat(output.first().serial).isEqualTo("xx") diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/reverse/RemoveReversePortForwardRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/reverse/RemoveReversePortForwardRequestTest.kt index 6b7e4fe58..c581bcb8f 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/reverse/RemoveReversePortForwardRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/reverse/RemoveReversePortForwardRequestTest.kt @@ -36,7 +36,9 @@ class RemoveReversePortForwardRequestTest { fun testDummy() { runBlocking { assertThat(RemoveReversePortForwardRequest(RemoteTcpPortSpec(8080)).transform()).isEqualTo(Unit) - assertThat(RemoveReversePortForwardRequest(RemoteTcpPortSpec(8080)).process(ByteArray(1), 0, 1)).isEqualTo(Unit) + assertThat( + RemoveReversePortForwardRequest(RemoteTcpPortSpec(8080)).process(ByteArray(1), 0, 1), + ).isEqualTo(Unit) } } } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardRequestTest.kt index db72a683f..3b829ef6a 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/reverse/ReversePortForwardRequestTest.kt @@ -48,7 +48,7 @@ class ReversePortForwardRequestTest { val bytes = ReversePortForwardRequest( RemoteTcpPortSpec(80), LocalTcpPortSpec(80), - mode = PortForwardingMode.NO_REBIND + mode = PortForwardingMode.NO_REBIND, ).serialize() assertThat(String(bytes, Const.DEFAULT_TRANSPORT_ENCODING)) @@ -64,7 +64,10 @@ class ReversePortForwardRequestTest { respondPortForward(true, 7070) } - val output = client.execute(ReversePortForwardRequest(RemoteTcpPortSpec(8080), LocalTcpPortSpec(0)), "serial") + val output = client.execute( + ReversePortForwardRequest(RemoteTcpPortSpec(8080), LocalTcpPortSpec(0)), + "serial", + ) assertThat(output).isEqualTo(7070) } } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v1/ChanneledShellCommandRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v1/ChanneledShellCommandRequestTest.kt index 03fb3334a..65b2cbea5 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v1/ChanneledShellCommandRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v1/ChanneledShellCommandRequestTest.kt @@ -41,7 +41,11 @@ class ChanneledShellCommandRequestTest { .respond("something2-something2") } - val updates = client.execute(ChanneledShellCommandRequest("logcat -v"), scope = this, serial = "emulator-5554") + val updates = client.execute( + ChanneledShellCommandRequest("logcat -v"), + scope = this, + serial = "emulator-5554", + ) val stringBuffer = StringBuffer() for (update in updates) { diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v1/ShellCommandRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v1/ShellCommandRequestTest.kt index fab2afb46..e7b189c30 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v1/ShellCommandRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v1/ShellCommandRequestTest.kt @@ -24,7 +24,6 @@ import kotlinx.coroutines.runBlocking import org.junit.Rule import org.junit.Test - class ShellCommandRequestTest { @get:Rule val server = AdbServerRule() diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v1/ShellResultResponseTransformerTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v1/ShellResultResponseTransformerTest.kt index ea3b36551..088460134 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v1/ShellResultResponseTransformerTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v1/ShellResultResponseTransformerTest.kt @@ -40,4 +40,4 @@ class ShellResultResponseTransformerTest { }.transform() } } -} \ No newline at end of file +} diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v2/ChanneledShellCommandRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v2/ChanneledShellCommandRequestTest.kt index 09e1a65cd..3cfacfe64 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v2/ChanneledShellCommandRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v2/ChanneledShellCommandRequestTest.kt @@ -60,7 +60,7 @@ class ChanneledShellCommandRequestTest { val updates = client.execute( ChanneledShellCommandRequest("echo foo; echo bar >&2; exit 17", stdio), scope = this, - serial = "serial" + serial = "serial", ) val stdoutBuffer = StringBuffer() val stderrBuffer = StringBuffer() diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandRequestTest.kt index d7cd52756..2e3780785 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/shell/v2/ShellCommandRequestTest.kt @@ -45,7 +45,6 @@ class ShellCommandRequestTest { respondShellV2Exit(17) } - val output = client.execute(ShellCommandRequest("echo foo; echo bar >&2; exit 17"), serial = "serial") assertThat(output.output).isEqualTo("foo\n") assertThat(output.errorOutput).isEqualTo("bar\n") diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/ListFilesRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/ListFilesRequestTest.kt index c5dd79634..913d4c482 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/ListFilesRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/ListFilesRequestTest.kt @@ -51,7 +51,7 @@ class ListFilesRequestTest { drwxrwx--x 2 root sdcard_rw 4096 2020-10-24 16:29 Ringtones Orwxrwx--x 2 root sdcard_rw 4096 2020-10-24 16:29 XXX x0 - """.trimIndent() + """.trimIndent(), ) } @@ -67,7 +67,7 @@ class ListFilesRequestTest { owner = "root", size = 4096, time = "16:29", - type = AndroidFileType.REGULAR_FILE + type = AndroidFileType.REGULAR_FILE, ), AndroidFile( permissions = "brwxrwx--x", @@ -79,7 +79,7 @@ class ListFilesRequestTest { owner = "root", size = 4096, time = "16:29", - type = AndroidFileType.BLOCK_SPECIAL_FILE + type = AndroidFileType.BLOCK_SPECIAL_FILE, ), AndroidFile( permissions = "lrwxrwx--x", @@ -91,7 +91,7 @@ class ListFilesRequestTest { owner = "root", size = 4096, time = "16:29", - type = AndroidFileType.SYMBOLIC_LINK + type = AndroidFileType.SYMBOLIC_LINK, ), AndroidFile( permissions = "crwxrwx--x", @@ -103,7 +103,7 @@ class ListFilesRequestTest { owner = "root", size = 4096, time = "19:11", - type = AndroidFileType.CHARACTER_SPECIAL_FILE + type = AndroidFileType.CHARACTER_SPECIAL_FILE, ), AndroidFile( permissions = "srwxrwx--x", @@ -115,7 +115,7 @@ class ListFilesRequestTest { owner = "root", size = 4096, time = "16:29", - type = AndroidFileType.SOCKET_LINK + type = AndroidFileType.SOCKET_LINK, ), AndroidFile( permissions = "prwxrwx--x", @@ -127,7 +127,7 @@ class ListFilesRequestTest { owner = "root", size = 4096, time = "16:29", - type = AndroidFileType.FIFO + type = AndroidFileType.FIFO, ), AndroidFile( permissions = "drwxrwx--x", @@ -139,8 +139,8 @@ class ListFilesRequestTest { owner = "root", size = 4096, time = "16:29", - type = AndroidFileType.DIRECTORY - ) + type = AndroidFileType.DIRECTORY, + ), ) assertThat(files.first().permissions).isEqualTo("-rwxrwx--x") diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/compat/CompatListFileRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/compat/CompatListFileRequestTest.kt index 8a8d87167..7fbca3dfa 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/compat/CompatListFileRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/compat/CompatListFileRequestTest.kt @@ -46,12 +46,13 @@ class CompatListFileRequestTest { 420, 123, 1589042331, - "some-file" + "some-file", ).done() } val list = client.execute( - CompatListFileRequest("/sdcard/", emptyList()), "serial" + CompatListFileRequest("/sdcard/", emptyList()), + "serial", ) assertThat(list).containsExactly( @@ -59,8 +60,8 @@ class CompatListFileRequestTest { name = "some-file", mode = 123.toUInt(), mtime = Instant.ofEpochSecond(1589042331), - size = 420.toUInt() - ) + size = 420.toUInt(), + ), ) } } @@ -84,12 +85,13 @@ class CompatListFileRequestTest { gid = 1000, atime = 1589042331, mtime = 1589042332, - ctime = 1589042333 + ctime = 1589042333, ).done() } val list = client.execute( - CompatListFileRequest("/sdcard/", listOf(Feature.LS_V2)), "serial" + CompatListFileRequest("/sdcard/", listOf(Feature.LS_V2)), + "serial", ) assertThat(list).containsExactly( @@ -105,8 +107,8 @@ class CompatListFileRequestTest { gid = 1000.toUInt(), atime = Instant.ofEpochSecond(1589042331), mtime = Instant.ofEpochSecond(1589042332), - ctime = Instant.ofEpochSecond(1589042333) - ) + ctime = Instant.ofEpochSecond(1589042333), + ), ) } } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/compat/CompatStatFileRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/compat/CompatStatFileRequestTest.kt index f722fd777..81d810975 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/compat/CompatStatFileRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/compat/CompatStatFileRequestTest.kt @@ -72,11 +72,14 @@ class CompatStatFileRequestTest { gid = 1000, atime = 1589042331, mtime = 1589042332, - ctime = 1589042333 + ctime = 1589042333, ) } - val result = client.execute(CompatStatFileRequest("/sdcard/testfile", listOf(Feature.STAT_V2)), serial = "serial") + val result = client.execute( + CompatStatFileRequest("/sdcard/testfile", listOf(Feature.STAT_V2)), + serial = "serial", + ) val output = result as FileEntryV2 assertThat(output).isEqualTo( FileEntryV2( @@ -90,8 +93,8 @@ class CompatStatFileRequestTest { gid = 1000.toUInt(), atime = Instant.ofEpochSecond(1589042331), mtime = Instant.ofEpochSecond(1589042332), - ctime = Instant.ofEpochSecond(1589042333) - ) + ctime = Instant.ofEpochSecond(1589042333), + ), ) } } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/ListFileRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/ListFileRequestTest.kt index 919aae4cc..9c5455a39 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/ListFileRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/ListFileRequestTest.kt @@ -44,22 +44,22 @@ class ListFileRequestTest { 420, 123, 1589042331, - "some-file" + "some-file", ).done() } val list = client.execute( - ListFileRequest("/sdcard/"), "serial" + ListFileRequest("/sdcard/"), + "serial", ) - assertThat(list).containsExactly( FileEntryV1( name = "some-file", mode = 123.toUInt(), mtime = Instant.ofEpochSecond(1589042331), - size = 420.toUInt() - ) + size = 420.toUInt(), + ), ) assertThat(list.first().name).isEqualTo("some-file") diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/PullFileRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/PullFileRequestTest.kt index 10664944b..ea45db03a 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/PullFileRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/PullFileRequestTest.kt @@ -24,7 +24,6 @@ import com.malinskiy.adam.exception.PullFailedException import com.malinskiy.adam.exception.UnsupportedSyncProtocolException import com.malinskiy.adam.server.junit4.AdbServerRule import io.ktor.utils.io.discard - import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.junit.Rule @@ -45,7 +44,12 @@ class PullFileRequestTest { @Test fun testSerialize() { - assertThat(String(PullFileRequest("/sdcard/testfile", File("/tmp/testfile")).serialize(), Const.DEFAULT_TRANSPORT_ENCODING)) + assertThat( + String( + PullFileRequest("/sdcard/testfile", File("/tmp/testfile")).serialize(), + Const.DEFAULT_TRANSPORT_ENCODING, + ), + ) .isEqualTo("0005sync:") } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/PushFileRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/PushFileRequestTest.kt index 41a936e7a..39ababf29 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/PushFileRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/PushFileRequestTest.kt @@ -106,7 +106,6 @@ class PushFileRequestTest { } }.join() - assertThat(receiveFile.readBytes()).isEqualTo(fixture.readBytes()) } } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/StatFileRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/StatFileRequestTest.kt index 43feebf62..05e1bdd64 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/StatFileRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v1/StatFileRequestTest.kt @@ -25,7 +25,6 @@ import org.junit.Rule import org.junit.Test import java.time.Instant - class StatFileRequestTest { @get:Rule val server = AdbServerRule() diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/ListFileRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/ListFileRequestTest.kt index de44697a7..b3c785c30 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/ListFileRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/ListFileRequestTest.kt @@ -54,13 +54,14 @@ class ListFileRequestTest { gid = 1000, atime = 1589042331, mtime = 1589042332, - ctime = 1589042333 + ctime = 1589042333, ) output.respondDone() } val list = client.execute( - ListFileRequest("/sdcard/", listOf(Feature.LS_V2)), "serial" + ListFileRequest("/sdcard/", listOf(Feature.LS_V2)), + "serial", ) assertThat(list).containsExactly( @@ -76,8 +77,8 @@ class ListFileRequestTest { gid = 1000.toUInt(), atime = Instant.ofEpochSecond(1589042331), mtime = Instant.ofEpochSecond(1589042332), - ctime = Instant.ofEpochSecond(1589042333) - ) + ctime = Instant.ofEpochSecond(1589042333), + ), ) assertThat(list.first().name).isEqualTo("some-file") diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/PullFileRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/PullFileRequestTest.kt index c33f212fe..de0a859db 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/PullFileRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/PullFileRequestTest.kt @@ -25,7 +25,6 @@ import com.malinskiy.adam.exception.UnsupportedSyncProtocolException import com.malinskiy.adam.request.Feature import com.malinskiy.adam.server.junit4.AdbServerRule import io.ktor.utils.io.discard - import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.junit.Rule @@ -49,8 +48,8 @@ class PullFileRequestTest { assertThat( String( PullFileRequest("/sdcard/testfile", File("/tmp/testfile"), listOf(Feature.SENDRECV_V2)).serialize(), - Const.DEFAULT_TRANSPORT_ENCODING - ) + Const.DEFAULT_TRANSPORT_ENCODING, + ), ) .isEqualTo("0005sync:") } @@ -77,7 +76,12 @@ class PullFileRequestTest { } val request = - PullFileRequest("/sdcard/testfile", tempFile, listOf(Feature.SENDRECV_V2), coroutineContext = coroutineContext) + PullFileRequest( + "/sdcard/testfile", + tempFile, + listOf(Feature.SENDRECV_V2), + coroutineContext = coroutineContext, + ) val execute = client.execute(request, this, "serial") var progress = 0.0 @@ -117,7 +121,12 @@ class PullFileRequestTest { } val request = - PullFileRequest("/sdcard/testfile", tempFile, listOf(Feature.SENDRECV_V2), coroutineContext = coroutineContext) + PullFileRequest( + "/sdcard/testfile", + tempFile, + listOf(Feature.SENDRECV_V2), + coroutineContext = coroutineContext, + ) val execute = client.execute(request, this, "serial") var progress = 0.0 diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/PushFileRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/PushFileRequestTest.kt index 4637b9743..805e38cbd 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/PushFileRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/PushFileRequestTest.kt @@ -75,7 +75,6 @@ class PushFileRequestTest { } assertThat(progress).isEqualTo(1.0) - }.join() assertThat(receiveFile.readBytes()).isEqualTo(fixture.readBytes()) diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/StatFileRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/StatFileRequestTest.kt index 4e0309956..b8c120482 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/StatFileRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/sync/v2/StatFileRequestTest.kt @@ -27,7 +27,6 @@ import org.junit.Rule import org.junit.Test import java.time.Instant - class StatFileRequestTest { @get:Rule val server = AdbServerRule() @@ -53,11 +52,14 @@ class StatFileRequestTest { gid = 1000, atime = 1589042331, mtime = 1589042332, - ctime = 1589042333 + ctime = 1589042333, ) } - val output: FileEntryV2 = client.execute(StatFileRequest("/sdcard/testfile", listOf(Feature.STAT_V2)), serial = "serial") + val output: FileEntryV2 = client.execute( + StatFileRequest("/sdcard/testfile", listOf(Feature.STAT_V2)), + serial = "serial", + ) assertThat(output).isEqualTo( FileEntryV2( mode = 123.toUInt(), @@ -70,10 +72,9 @@ class StatFileRequestTest { gid = 1000.toUInt(), atime = Instant.ofEpochSecond(1589042331), mtime = Instant.ofEpochSecond(1589042332), - ctime = Instant.ofEpochSecond(1589042333) - ) + ctime = Instant.ofEpochSecond(1589042333), + ), ) } } - } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/InstrumentOptionsTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/InstrumentOptionsTest.kt index ac607e159..95d266380 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/InstrumentOptionsTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/InstrumentOptionsTest.kt @@ -41,21 +41,21 @@ class InstrumentOptionsTest { functional = true, log = true, performance = true, - unit = true + unit = true, ) assertThat(options.toString()).isEqualTo( " -e package com.example " + - "-e class com.example.TestClass " + - "-e func true " + - "-e unit true " + - "-e size medium " + - "-e perf true " + - "-e debug true " + - "-e log true " + - "-e emma true " + - "-e coverageFile /sdcard/codecov " + - "-e test test" + "-e class com.example.TestClass " + + "-e func true " + + "-e unit true " + + "-e size medium " + + "-e perf true " + + "-e debug true " + + "-e log true " + + "-e emma true " + + "-e coverageFile /sdcard/codecov " + + "-e test test", ) } @@ -72,7 +72,7 @@ class InstrumentOptionsTest { functional = true, log = true, performance = true, - unit = true + unit = true, ) assertThat(options.pkg).containsExactly("com.example") @@ -93,13 +93,13 @@ class InstrumentOptionsTest { val options = InstrumentOptions( overrides = mapOf( "param1" to "value1", - "param2" to "value2" - ) + "param2" to "value2", + ), ) assertThat(options.toString()).isEqualTo( " -e param1 value1" + - " -e param2 value2" + " -e param2 value2", ) } } diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/TestRunnerRequestTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/TestRunnerRequestTest.kt index 6feec4bc3..f6b076886 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/TestRunnerRequestTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/TestRunnerRequestTest.kt @@ -50,13 +50,13 @@ class TestRunnerRequestTest { runnerClass = "com.example.test.AndroidTestRunner", userId = 1000, supportedFeatures = emptyList(), - coroutineScope = this + coroutineScope = this, ) assertThat(request.cmd) .isEqualTo( "am instrument -w -r --no-hidden-api-checks --no-window-animation --user 1000 --abi x86 " + - "-p /sdcard/profiling -f /sdcard/log com.example.test/com.example.test.AndroidTestRunner" + "-p /sdcard/profiling -f /sdcard/log com.example.test/com.example.test.AndroidTestRunner", ) } } @@ -68,12 +68,12 @@ class TestRunnerRequestTest { testPackage = "com.example.test", instrumentOptions = InstrumentOptions(), supportedFeatures = emptyList(), - coroutineScope = this + coroutineScope = this, ) assertThat(request.cmd) .isEqualTo( - "am instrument -w -r com.example.test/android.support.test.runner.AndroidJUnitRunner" + "am instrument -w -r com.example.test/android.support.test.runner.AndroidJUnitRunner", ) } } @@ -84,7 +84,9 @@ class TestRunnerRequestTest { launch { server.session { expectCmd { "host:transport:serial" }.accept() - expectShell { "am instrument -w -r com.example.test/android.support.test.runner.AndroidJUnitRunner" } + expectShell { + "am instrument -w -r com.example.test/android.support.test.runner.AndroidJUnitRunner" + } .accept() .respond( """ @@ -111,7 +113,7 @@ class TestRunnerRequestTest { INSTRUMENTATION_CODE: -1 - """.trimIndent() + """.trimIndent(), ) } @@ -120,7 +122,7 @@ class TestRunnerRequestTest { testPackage = "com.example.test", instrumentOptions = InstrumentOptions(), supportedFeatures = emptyList(), - coroutineScope = this + coroutineScope = this, ), serial = "serial", ) @@ -132,12 +134,14 @@ class TestRunnerRequestTest { assertThat(events).containsExactly( TestRunStartedEvent(testCount = 1), - TestStarted(id = TestIdentifier(className = "com.example.MainActivityAllureTest", testName = "testText")), + TestStarted( + id = TestIdentifier(className = "com.example.MainActivityAllureTest", testName = "testText"), + ), TestEnded( id = TestIdentifier(className = "com.example.MainActivityAllureTest", testName = "testText"), - metrics = emptyMap() + metrics = emptyMap(), ), - TestRunEnded(elapsedTimeMillis = 0, metrics = emptyMap()) + TestRunEnded(elapsedTimeMillis = 0, metrics = emptyMap()), ) }.join() } @@ -149,7 +153,9 @@ class TestRunnerRequestTest { launch { server.session { expectCmd { "host:transport:serial" }.accept() - expectShellV2 { "am instrument -w -r com.example.test/android.support.test.runner.AndroidJUnitRunner" } + expectShellV2 { + "am instrument -w -r com.example.test/android.support.test.runner.AndroidJUnitRunner" + } .accept() .respondStdout( """ @@ -176,7 +182,7 @@ class TestRunnerRequestTest { INSTRUMENTATION_CODE: -1 - """.trimIndent() + """.trimIndent(), ) .respondExit(0) } @@ -186,7 +192,7 @@ class TestRunnerRequestTest { testPackage = "com.example.test", instrumentOptions = InstrumentOptions(), supportedFeatures = listOf(Feature.SHELL_V2), - coroutineScope = this + coroutineScope = this, ), serial = "serial", ) @@ -198,12 +204,14 @@ class TestRunnerRequestTest { assertThat(events).containsExactly( TestRunStartedEvent(testCount = 1), - TestStarted(id = TestIdentifier(className = "com.example.MainActivityAllureTest", testName = "testText")), + TestStarted( + id = TestIdentifier(className = "com.example.MainActivityAllureTest", testName = "testText"), + ), TestEnded( id = TestIdentifier(className = "com.example.MainActivityAllureTest", testName = "testText"), - metrics = emptyMap() + metrics = emptyMap(), ), - TestRunEnded(elapsedTimeMillis = 0, metrics = emptyMap()) + TestRunEnded(elapsedTimeMillis = 0, metrics = emptyMap()), ) }.join() } @@ -215,7 +223,9 @@ class TestRunnerRequestTest { launch { server.session { expectCmd { "host:transport:serial" }.accept() - expectShellV2 { "am instrument -w -r com.example.test/android.support.test.runner.AndroidJUnitRunner" } + expectShellV2 { + "am instrument -w -r com.example.test/android.support.test.runner.AndroidJUnitRunner" + } .accept() .respondStdout( """ @@ -225,18 +235,18 @@ class TestRunnerRequestTest { INSTRUMENTATION_STATUS: numtests=1 INSTRUMENTATION_STATUS: stream= com.example.MainActivityAllureTest: - INSTRUMENTATION_STATUS: test=testText - """.trimIndent() + INSTRUMENTATION_STATUS: test=testText + """.trimIndent(), ) .respondStderr( """ s_glBindAttribLocation: bind attrib 0 name position s_glBindAttribLocation: bind attrib 1 name localCoord - """.trimIndent() + """.trimIndent(), ) .respondStdout( """ - + INSTRUMENTATION_STATUS_CODE: 1 INSTRUMENTATION_STATUS: class=com.example.MainActivityAllureTest INSTRUMENTATION_STATUS: current=1 @@ -253,7 +263,7 @@ class TestRunnerRequestTest { INSTRUMENTATION_CODE: -1 - """.trimIndent() + """.trimIndent(), ) .respondExit(0) } @@ -263,7 +273,7 @@ class TestRunnerRequestTest { testPackage = "com.example.test", instrumentOptions = InstrumentOptions(), supportedFeatures = listOf(Feature.SHELL_V2), - coroutineScope = this + coroutineScope = this, ), serial = "serial", ) @@ -274,12 +284,14 @@ class TestRunnerRequestTest { assertThat(events).containsExactly( TestRunStartedEvent(testCount = 1), - TestStarted(id = TestIdentifier(className = "com.example.MainActivityAllureTest", testName = "testText")), + TestStarted( + id = TestIdentifier(className = "com.example.MainActivityAllureTest", testName = "testText"), + ), TestEnded( id = TestIdentifier(className = "com.example.MainActivityAllureTest", testName = "testText"), - metrics = emptyMap() + metrics = emptyMap(), ), - TestRunEnded(elapsedTimeMillis = 0, metrics = emptyMap()) + TestRunEnded(elapsedTimeMillis = 0, metrics = emptyMap()), ) }.join() } @@ -291,7 +303,9 @@ class TestRunnerRequestTest { launch { server.session { expectCmd { "host:transport:serial" }.accept() - expectShell { "am instrument -w -r com.example.test/android.support.test.runner.AndroidJUnitRunner" } + expectShell { + "am instrument -w -r com.example.test/android.support.test.runner.AndroidJUnitRunner" + } .accept() .respond("something-something") } @@ -301,7 +315,7 @@ class TestRunnerRequestTest { testPackage = "com.example.test", instrumentOptions = InstrumentOptions(), supportedFeatures = emptyList(), - coroutineScope = this + coroutineScope = this, ), serial = "serial", ) diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformerTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformerTest.kt index 5923ec58d..d027981e3 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformerTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformerTest.kt @@ -168,7 +168,8 @@ class InstrumentationResponseTransformerTest { fun testBufferFraming() = runBlocking { val transformer = InstrumentationResponseTransformer() - val lines = javaClass.getResourceAsStream("/instrumentation/log_6.input").reader().readLines() + val lines = javaClass.getResourceAsStream( + "/instrumentation/log_6.input").reader().readLines() val events = mutableListOf() for (line in lines) { diff --git a/android-junit4-test-annotation-producer/build.gradle.kts b/android-junit4-test-annotation-producer/build.gradle.kts index a5936eaaa..04e8df7fd 100644 --- a/android-junit4-test-annotation-producer/build.gradle.kts +++ b/android-junit4-test-annotation-producer/build.gradle.kts @@ -25,4 +25,4 @@ android { dependencies { implementation(libs.kotlin.reflect) -} \ No newline at end of file +} diff --git a/android-junit4-test-annotation-producer/src/main/kotlin/com/malinskiy/adam/junit4/android/listener/TestAnnotationProducer.kt b/android-junit4-test-annotation-producer/src/main/kotlin/com/malinskiy/adam/junit4/android/listener/TestAnnotationProducer.kt index 7528dfec4..47ec4ba8b 100644 --- a/android-junit4-test-annotation-producer/src/main/kotlin/com/malinskiy/adam/junit4/android/listener/TestAnnotationProducer.kt +++ b/android-junit4-test-annotation-producer/src/main/kotlin/com/malinskiy/adam/junit4/android/listener/TestAnnotationProducer.kt @@ -47,7 +47,10 @@ public class TestAnnotationProducer : RunListener() { super.testStarted(description) if (description?.isTest == true) { val annotations: Set = - (description.annotations.toList() + description.testClass.annotations.toList()).mapNotNull { annotation -> + ( + description.annotations.toList() + + description.testClass.annotations.toList() + ).mapNotNull { annotation -> val fqn = annotation.annotationClass.qualifiedName val parameters = annotation.annotationClass.memberProperties.joinToString("") { @@ -60,7 +63,7 @@ public class TestAnnotationProducer : RunListener() { val bundle = Bundle(1) bundle.putStringArrayList( "com.malinskiy.adam.junit4.android.listener.TestAnnotationProducer.v4", - ArrayList(annotations) + ArrayList(annotations), ) InstrumentationRegistry.getInstrumentation().sendStatus(2, bundle) } diff --git a/android-junit4/build.gradle.kts b/android-junit4/build.gradle.kts index ed1f50f81..e0e254843 100644 --- a/android-junit4/build.gradle.kts +++ b/android-junit4/build.gradle.kts @@ -28,4 +28,3 @@ dependencies { api(libs.coroutines.core) api(project(":android-testrunner-contract")) } - diff --git a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/UnsafeAdbAccess.kt b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/UnsafeAdbAccess.kt index 3158b13bc..a21887642 100644 --- a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/UnsafeAdbAccess.kt +++ b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/UnsafeAdbAccess.kt @@ -3,8 +3,10 @@ package com.malinskiy.adam.junit4.android @Retention(value = AnnotationRetention.BINARY) @RequiresOptIn( level = RequiresOptIn.Level.WARNING, - message = "This implementation of adb is unsafe: unrestricted access to adb can introduce side-effects as well as unpredictable behaviour. " + - "Its usage should be marked with '@com.malinskiy.adam.junit4.android.UnsafeAdbAccess' or '@OptIn(com.malinskiy.adam.junit4.android.UnsafeAdbAccess::class)' " + - "if you accept the potential risks" + message = "This implementation of adb is unsafe: unrestricted access to adb can " + + "introduce side-effects as well as unpredictable behaviour. " + + "Its usage should be marked with '@com.malinskiy.adam.junit4.android.UnsafeAdbAccess'" + + " or '@OptIn(com.malinskiy.adam.junit4.android.UnsafeAdbAccess::class)' " + + "if you accept the potential risks", ) public annotation class UnsafeAdbAccess diff --git a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/AdbRule.kt b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/AdbRule.kt index 2c4a8bcf9..b03808328 100644 --- a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/AdbRule.kt +++ b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/AdbRule.kt @@ -35,7 +35,10 @@ import kotlin.coroutines.CoroutineContext * @param coroutineContext it's your responsibility to cancel this context when needed */ @OptIn(UnsafeAdbAccess::class) -public class AdbRule(private val mode: Mode = Mode.ASSERT, private val coroutineContext: CoroutineContext = Dispatchers.IO) : +public class AdbRule( + private val mode: Mode = Mode.ASSERT, + private val coroutineContext: CoroutineContext = Dispatchers.IO, +) : TestRule { public lateinit var adb: SingleTargetAndroidDebugBridgeClient @@ -61,7 +64,11 @@ public class AdbRule(private val mode: Mode = Mode.ASSERT, private val coroutine } else { when (mode) { Mode.SKIP -> return - Mode.ASSUME -> throw AssumptionViolatedException("No access to adb port or device serial has been provided") + + Mode.ASSUME -> throw AssumptionViolatedException( + "No access to adb port or device serial has been provided", + ) + Mode.ASSERT -> throw AssertionError("No access to adb port or device serial has been provided") } } diff --git a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/EmulatorConsoleRule.kt b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/EmulatorConsoleRule.kt index f5cfa9385..113892df3 100644 --- a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/EmulatorConsoleRule.kt +++ b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/EmulatorConsoleRule.kt @@ -32,7 +32,10 @@ import kotlin.coroutines.CoroutineContext /** * @param coroutineContext it's your responsibility to cancel this context when needed */ -public class EmulatorConsoleRule(private val mode: Mode = Mode.ASSERT, private val coroutineContext: CoroutineContext = Dispatchers.IO) : +public class EmulatorConsoleRule( + private val mode: Mode = Mode.ASSERT, + private val coroutineContext: CoroutineContext = Dispatchers.IO, +) : TestRule { private lateinit var client: AndroidDebugBridgeClient private lateinit var inetSocketAddress: InetSocketAddress @@ -54,8 +57,14 @@ public class EmulatorConsoleRule(private val mode: Mode = Mode.ASSERT, private v } else { when (mode) { Mode.SKIP -> return - Mode.ASSUME -> throw AssumptionViolatedException("No access to console port: host = $host, port = $port, token = $authToken") - Mode.ASSERT -> throw AssertionError("No access to console port: host = $host, port = $port, token = $authToken") + + Mode.ASSUME -> throw AssumptionViolatedException( + "No access to console port: host = $host, port = $port, token = $authToken", + ) + + Mode.ASSERT -> throw AssertionError( + "No access to console port: host = $host, port = $port, token = $authToken", + ) } } @@ -68,5 +77,7 @@ public class EmulatorConsoleRule(private val mode: Mode = Mode.ASSERT, private v } } - public suspend fun execute(cmd: String): String = client.execute(EmulatorCommandRequest(cmd, inetSocketAddress, authToken)) + public suspend fun execute(cmd: String): String = client.execute( + EmulatorCommandRequest(cmd, inetSocketAddress, authToken), + ) } diff --git a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/EmulatorGrpcRule.kt b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/EmulatorGrpcRule.kt index 940c31d0f..406fdcce2 100644 --- a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/EmulatorGrpcRule.kt +++ b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/EmulatorGrpcRule.kt @@ -33,7 +33,7 @@ import java.util.concurrent.TimeUnit public class EmulatorGrpcRule( public val mode: Mode = Mode.ASSERT, - private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO + private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO, ) : TestRule { public lateinit var grpc: EmulatorControllerGrpcKt.EmulatorControllerCoroutineStub private var channel: ManagedChannel? = null @@ -55,8 +55,14 @@ public class EmulatorGrpcRule( } else { when (mode) { Mode.SKIP -> return - Mode.ASSUME -> throw AssumptionViolatedException("No access to emulator's gRPC port has been provided: host = $grpcHost, port = $grpcPort") - Mode.ASSERT -> throw AssertionError("No access to emulator's gRPC port has been provided: host = $grpcHost, port = $grpcPort") + + Mode.ASSUME -> throw AssumptionViolatedException( + "No access to emulator's gRPC port has been provided: host = $grpcHost, port = $grpcPort", + ) + + Mode.ASSERT -> throw AssertionError( + "No access to emulator's gRPC port has been provided: host = $grpcHost, port = $grpcPort", + ) } } diff --git a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/Mode.kt b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/Mode.kt index 87691cfae..9de400a2f 100644 --- a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/Mode.kt +++ b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/Mode.kt @@ -30,5 +30,5 @@ public enum class Mode { /** * Assert failure if the rule can't be satisfied */ - ASSERT + ASSERT, } diff --git a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/sandbox/SingleTargetAndroidDebugBridgeClient.kt b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/sandbox/SingleTargetAndroidDebugBridgeClient.kt index ed49ee242..2e7ef38f9 100644 --- a/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/sandbox/SingleTargetAndroidDebugBridgeClient.kt +++ b/android-junit4/src/main/kotlin/com/malinskiy/adam/junit4/android/rule/sandbox/SingleTargetAndroidDebugBridgeClient.kt @@ -23,12 +23,17 @@ import com.malinskiy.adam.request.MultiRequest import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.ReceiveChannel -public class SingleTargetAndroidDebugBridgeClient(private val client: AndroidDebugBridgeClient, private val serial: String) { +public class SingleTargetAndroidDebugBridgeClient( + private val client: AndroidDebugBridgeClient, + private val serial: String, +) { public suspend fun execute(request: ComplexRequest): T = client.execute(request, serial) - public fun execute(request: AsyncChannelRequest, scope: CoroutineScope): ReceiveChannel = - client.execute(request, scope, serial) + public fun execute( + request: AsyncChannelRequest, + scope: CoroutineScope, + ): ReceiveChannel = client.execute(request, scope, serial) public suspend fun execute(request: MultiRequest): T = client.execute(request, serial) } diff --git a/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureProcessor.kt b/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureProcessor.kt index b857f8928..b8b80a730 100644 --- a/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureProcessor.kt +++ b/androidx-screencapture/src/main/kotlin/com/malinskiy/adam/junit4/android/screencapture/AdamScreenCaptureProcessor.kt @@ -52,7 +52,7 @@ public class AdamScreenCaptureProcessor : BasicScreenCaptureProcessor() { val bundle = Bundle(1) bundle.putString( "com.malinskiy.adam.junit4.android.screencapture.AdamScreenCaptureProcessor.v1", - absoluteScreenCapturePath.absolutePath + absoluteScreenCapturePath.absolutePath, ) InstrumentationRegistry.getInstrumentation().sendStatus(2, bundle) return filename diff --git a/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketFactory.kt b/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketFactory.kt index 36ec11e12..58ff8496f 100644 --- a/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketFactory.kt +++ b/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketFactory.kt @@ -28,7 +28,7 @@ import io.ktor.network.sockets.InetSocketAddress as KtorSocketAddress public class KtorSocketFactory( coroutineContext: CoroutineContext, private val connectTimeout: Long = 10_000, - private val idleTimeout: Long = 30_000 + private val idleTimeout: Long = 30_000, ) : SocketFactory { private val selectorManager: SelectorManager = SelectorManager(coroutineContext) @@ -39,7 +39,8 @@ public class KtorSocketFactory( .tcp() .connect(ktorSocketAddress) { socketTimeout = idleTimeout ?: this@KtorSocketFactory.idleTimeout - }) + }, + ) } override fun close() { From b7dcf83b0c755077bd80bf96db2865f5fb0eea0f Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sat, 14 Feb 2026 18:00:34 +0000 Subject: [PATCH 13/50] ci: update dokka task to generate HTML documentation --- .github/workflows/github-pages.yml | 2 +- adam/build.gradle.kts | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml index efbfd4786..8bc5e6bad 100644 --- a/.github/workflows/github-pages.yml +++ b/.github/workflows/github-pages.yml @@ -16,7 +16,7 @@ jobs: distribution: 'temurin' java-version: '11' - name: Generate dokka files - run: ./gradlew :adam:dokkaHtml + run: ./gradlew :adam:dokkaGenerate - uses: helaili/jekyll-action@2.0.4 env: JEKYLL_PAT: ${{ secrets.JEKYLL_PAT }} diff --git a/adam/build.gradle.kts b/adam/build.gradle.kts index e4bae4635..248055da4 100644 --- a/adam/build.gradle.kts +++ b/adam/build.gradle.kts @@ -138,8 +138,10 @@ tasks.jacocoTestReport { } } -tasks.dokkaHtml.configure { - outputDirectory.set(rootProject.rootDir.resolve("docs/api")) +dokka { + dokkaPublications.html { + outputDirectory.set(rootProject.rootDir.resolve("docs/api")) + } } dependencies { From 08cf4d8e3941afb002841fe917398b4e09ef8b77 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sat, 14 Feb 2026 18:17:51 +0000 Subject: [PATCH 14/50] fix: address code review --- .../adam/server/stub/ServerReadChannel.kt | 9 +++--- .../adam/server/stub/ServerWriteChannel.kt | 8 ++--- .../malinskiy/adam/server/stub/StubSocket.kt | 22 +++++--------- .../adam/transport/ktor/KtorSocket.kt | 30 +++++-------------- 4 files changed, 24 insertions(+), 45 deletions(-) diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerReadChannel.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerReadChannel.kt index 2f8959433..5d038656d 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerReadChannel.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerReadChannel.kt @@ -25,8 +25,8 @@ import com.malinskiy.adam.request.shell.v2.MessageType import com.malinskiy.adam.request.sync.v2.CompressionType import io.ktor.util.cio.writeChannel import io.ktor.utils.io.ByteReadChannel -import io.ktor.utils.io.readByteArray -import io.ktor.utils.io.writeByteArray +import io.ktor.utils.io.readFully +import io.ktor.utils.io.writeFully import io.ktor.utils.io.readByte as channelReadByte import io.ktor.utils.io.readInt as channelReadInt import kotlinx.coroutines.Job @@ -40,8 +40,7 @@ public class ServerReadChannel(private val delegate: ByteReadChannel) : ByteRead public suspend fun readIntLittleEndian(): Int = Integer.reverseBytes(delegate.channelReadInt()) public suspend fun readFully(dst: ByteArray, offset: Int, length: Int) { - val tmp = delegate.readByteArray(length) - System.arraycopy(tmp, 0, dst, offset, length) + delegate.readFully(dst, offset, offset + length) } public suspend fun receiveCommand(): String { val bytes = ByteArray(4) @@ -197,7 +196,7 @@ public class ServerReadChannel(private val delegate: ByteReadChannel) : ByteRead throw UnsupportedSyncProtocolException() } readFully(dataBuffer, 0, available) - channel.writeByteArray(dataBuffer.copyOfRange(0, available)) + channel.writeFully(dataBuffer, 0, available) } else -> throw RuntimeException("Something bad happened") } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerWriteChannel.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerWriteChannel.kt index 7b762e2b4..a64078638 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerWriteChannel.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerWriteChannel.kt @@ -19,7 +19,7 @@ package com.malinskiy.adam.server.stub import com.malinskiy.adam.Const import com.malinskiy.adam.request.shell.v2.MessageType import io.ktor.utils.io.ByteWriteChannel -import io.ktor.utils.io.writeByteArray +import io.ktor.utils.io.writeFully import io.ktor.utils.io.writeStringUtf8 import java.nio.ByteBuffer import io.ktor.utils.io.writeInt as channelWriteInt @@ -28,7 +28,7 @@ import io.ktor.utils.io.writeByte as channelWriteByte public class ServerWriteChannel(private val delegate: ByteWriteChannel) : ByteWriteChannel by delegate { private suspend fun write(request: ByteArray, length: Int? = null) { - delegate.writeByteArray(request.copyOfRange(0, length ?: request.size)) + delegate.writeFully(request, 0, length ?: request.size) } public suspend fun writeIntLittleEndian(value: Int) { @@ -40,11 +40,11 @@ public class ServerWriteChannel(private val delegate: ByteWriteChannel) : ByteWr } public suspend fun writeFully(src: ByteArray) { - delegate.writeByteArray(src) + delegate.writeFully(src) } public suspend fun writeFully(src: ByteArray, offset: Int, length: Int) { - delegate.writeByteArray(src.copyOfRange(offset, offset + length)) + delegate.writeFully(src, offset, offset + length) } public suspend fun writeByte(value: Byte) { diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/StubSocket.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/StubSocket.kt index 356bf6297..0ca878092 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/StubSocket.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/StubSocket.kt @@ -21,9 +21,10 @@ import io.ktor.utils.io.ByteChannel import io.ktor.utils.io.ByteReadChannel import io.ktor.utils.io.ByteWriteChannel import io.ktor.utils.io.cancel -import io.ktor.utils.io.readByteArray +import io.ktor.utils.io.readAvailable +import io.ktor.utils.io.readFully import io.ktor.utils.io.readInt -import io.ktor.utils.io.writeByteArray +import io.ktor.utils.io.writeFully import io.ktor.utils.io.writeInt import java.nio.ByteBuffer import io.ktor.utils.io.readByte as channelReadByte @@ -42,31 +43,24 @@ public class StubSocket( override suspend fun readFully(buffer: ByteBuffer): Int { val count = buffer.remaining() - val dst = readChannel.readByteArray(count) - buffer.put(dst) + readChannel.readFully(buffer) return count } override suspend fun readFully(buffer: ByteArray, offset: Int, limit: Int) { - val tmp = readChannel.readByteArray(limit) - System.arraycopy(tmp, 0, buffer, offset, limit) + readChannel.readFully(buffer, offset, offset + limit) } override suspend fun writeFully(byteBuffer: ByteBuffer) { - val src = ByteArray(byteBuffer.remaining()) - byteBuffer.get(src) - writeChannel.writeByteArray(src) + writeChannel.writeFully(byteBuffer) } override suspend fun writeFully(byteArray: ByteArray, offset: Int, limit: Int) { - writeChannel.writeByteArray(byteArray.copyOfRange(offset, offset + limit)) + writeChannel.writeFully(byteArray, offset, offset + limit) } override suspend fun readAvailable(buffer: ByteArray, offset: Int, limit: Int): Int { - if (readChannel.isClosedForRead) return -1 - val tmp = readChannel.readByteArray(limit.coerceAtMost(1)) - System.arraycopy(tmp, 0, buffer, offset, tmp.size) - return tmp.size + return readChannel.readAvailable(buffer, offset, limit) } override suspend fun readByte(): Byte = readChannel.channelReadByte() diff --git a/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocket.kt b/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocket.kt index cc0214237..f912d7e62 100644 --- a/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocket.kt +++ b/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocket.kt @@ -22,11 +22,11 @@ import io.ktor.network.sockets.openReadChannel import io.ktor.network.sockets.openWriteChannel import io.ktor.utils.io.ByteReadChannel import io.ktor.utils.io.ByteWriteChannel -import io.ktor.utils.io.availableForRead import io.ktor.utils.io.cancel -import io.ktor.utils.io.readByteArray +import io.ktor.utils.io.readAvailable +import io.ktor.utils.io.readFully import io.ktor.utils.io.readInt -import io.ktor.utils.io.writeByteArray +import io.ktor.utils.io.writeFully import io.ktor.utils.io.writeInt import java.nio.ByteBuffer import io.ktor.network.sockets.Socket as RealKtorSocket @@ -43,36 +43,24 @@ public class KtorSocket(private val ktorSocket: RealKtorSocket) : Socket { override suspend fun readFully(buffer: ByteBuffer): Int { val count = buffer.remaining() - val dst = readChannel.readByteArray(count) - buffer.put(dst) + readChannel.readFully(buffer) return count } override suspend fun readFully(buffer: ByteArray, offset: Int, limit: Int) { - val tmp = readChannel.readByteArray(limit) - System.arraycopy(tmp, 0, buffer, offset, limit) + readChannel.readFully(buffer, offset, offset + limit) } override suspend fun writeFully(byteBuffer: ByteBuffer) { - val src = ByteArray(byteBuffer.remaining()) - byteBuffer.get(src) - writeChannel.writeByteArray(src) - writeChannel.flush() + writeChannel.writeFully(byteBuffer) } override suspend fun writeFully(byteArray: ByteArray, offset: Int, limit: Int) { - writeChannel.writeByteArray(byteArray.copyOfRange(offset, offset + limit)) - writeChannel.flush() + writeChannel.writeFully(byteArray, offset, offset + limit) } override suspend fun readAvailable(buffer: ByteArray, offset: Int, limit: Int): Int { - if (readChannel.isClosedForRead && readChannel.availableForRead == 0) return -1 - val avail = readChannel.availableForRead - if (avail == 0) return 0 - val toRead = avail.coerceAtMost(limit) - val tmp = readChannel.readByteArray(toRead) - System.arraycopy(tmp, 0, buffer, offset, toRead) - return toRead + return readChannel.readAvailable(buffer, offset, limit) } override suspend fun readByte(): Byte = readChannel.ktorReadByte() @@ -81,12 +69,10 @@ public class KtorSocket(private val ktorSocket: RealKtorSocket) : Socket { override suspend fun writeByte(value: Int) { writeChannel.ktorWriteByte(value.toByte()) - writeChannel.flush() } override suspend fun writeIntLittleEndian(value: Int) { writeChannel.writeInt(Integer.reverseBytes(value)) - writeChannel.flush() } override suspend fun close() { From 637d5445617a764f6abf7fdded1713428d87d2ff Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sat, 14 Feb 2026 18:43:52 +0000 Subject: [PATCH 15/50] chore: update maven publishing plugin --- adam/build.gradle.kts | 29 ++++++++++++++++++ .../build.gradle.kts | 30 ++++++++++++++++++- android-junit4/build.gradle.kts | 30 ++++++++++++++++++- android-testrunner-contract/build.gradle.kts | 29 ++++++++++++++++++ androidx-screencapture/build.gradle.kts | 30 ++++++++++++++++++- build.gradle.kts | 25 ++++++++++++++++ gradle/libs.versions.toml | 2 ++ server/server-stub-junit4/build.gradle.kts | 29 ++++++++++++++++++ server/server-stub-junit5/build.gradle.kts | 29 ++++++++++++++++++ server/server-stub/build.gradle.kts | 29 ++++++++++++++++++ transport-ktor/build.gradle.kts | 29 ++++++++++++++++++ .../adam/transport/ktor/KtorSocket.kt | 2 ++ 12 files changed, 290 insertions(+), 3 deletions(-) diff --git a/adam/build.gradle.kts b/adam/build.gradle.kts index 248055da4..1c44ba5bd 100644 --- a/adam/build.gradle.kts +++ b/adam/build.gradle.kts @@ -22,9 +22,38 @@ plugins { id("jacoco") id("org.jetbrains.dokka") alias(libs.plugins.protobuf) + alias(libs.plugins.vanniktech.maven.publish) id("idea") } +mavenPublishing { + coordinates("com.github.ArthurKun21", "adam", version.toString()) + + pom { + name.set("adam") + description.set("Android Debug Bridge helper - core library") + url.set("https://github.com/ArthurKun21/adam") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("ArthurKun21") + name.set("Arthur") + email.set("16458204+ArthurKun21@users.noreply.github.com") + } + } + scm { + connection.set("scm:git:git://github.com/ArthurKun21/adam.git") + developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") + url.set("https://github.com/ArthurKun21/adam") + } + } +} + protobuf { protoc { artifact = "com.google.protobuf:protoc:${libs.versions.protobuf.get()}" diff --git a/android-junit4-test-annotation-producer/build.gradle.kts b/android-junit4-test-annotation-producer/build.gradle.kts index 04e8df7fd..58decd9d2 100644 --- a/android-junit4-test-annotation-producer/build.gradle.kts +++ b/android-junit4-test-annotation-producer/build.gradle.kts @@ -16,7 +16,35 @@ plugins { id("adam.android.library") - id("maven-publish") + alias(libs.plugins.vanniktech.maven.publish) +} + +mavenPublishing { + coordinates("com.github.ArthurKun21", "android-junit4-test-annotation-producer", version.toString()) + + pom { + name.set("android-junit4-test-annotation-producer") + description.set("Android Debug Bridge helper - Test annotation producer") + url.set("https://github.com/ArthurKun21/adam") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("ArthurKun21") + name.set("Arthur") + email.set("16458204+ArthurKun21@users.noreply.github.com") + } + } + scm { + connection.set("scm:git:git://github.com/ArthurKun21/adam.git") + developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") + url.set("https://github.com/ArthurKun21/adam") + } + } } android { diff --git a/android-junit4/build.gradle.kts b/android-junit4/build.gradle.kts index e0e254843..a0a441b91 100644 --- a/android-junit4/build.gradle.kts +++ b/android-junit4/build.gradle.kts @@ -16,7 +16,35 @@ plugins { id("adam.android.library") - id("maven-publish") + alias(libs.plugins.vanniktech.maven.publish) +} + +mavenPublishing { + coordinates("com.github.ArthurKun21", "android-junit4", version.toString()) + + pom { + name.set("android-junit4") + description.set("Android Debug Bridge helper - JUnit4 Android rules") + url.set("https://github.com/ArthurKun21/adam") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("ArthurKun21") + name.set("Arthur") + email.set("16458204+ArthurKun21@users.noreply.github.com") + } + } + scm { + connection.set("scm:git:git://github.com/ArthurKun21/adam.git") + developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") + url.set("https://github.com/ArthurKun21/adam") + } + } } android { diff --git a/android-testrunner-contract/build.gradle.kts b/android-testrunner-contract/build.gradle.kts index ceb613739..112528c08 100644 --- a/android-testrunner-contract/build.gradle.kts +++ b/android-testrunner-contract/build.gradle.kts @@ -18,6 +18,35 @@ import adam.buildlogic.ProjectConfig plugins { id("java") + alias(libs.plugins.vanniktech.maven.publish) +} + +mavenPublishing { + coordinates("com.github.ArthurKun21", "android-testrunner-contract", version.toString()) + + pom { + name.set("android-testrunner-contract") + description.set("Android Debug Bridge helper - Test runner contract") + url.set("https://github.com/ArthurKun21/adam") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("ArthurKun21") + name.set("Arthur") + email.set("16458204+ArthurKun21@users.noreply.github.com") + } + } + scm { + connection.set("scm:git:git://github.com/ArthurKun21/adam.git") + developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") + url.set("https://github.com/ArthurKun21/adam") + } + } } java { diff --git a/androidx-screencapture/build.gradle.kts b/androidx-screencapture/build.gradle.kts index d7a68372b..afab1ba0f 100644 --- a/androidx-screencapture/build.gradle.kts +++ b/androidx-screencapture/build.gradle.kts @@ -16,7 +16,35 @@ plugins { id("adam.android.library") - id("maven-publish") + alias(libs.plugins.vanniktech.maven.publish) +} + +mavenPublishing { + coordinates("com.github.ArthurKun21", "androidx-screencapture", version.toString()) + + pom { + name.set("androidx-screencapture") + description.set("Android Debug Bridge helper - Screen capture support") + url.set("https://github.com/ArthurKun21/adam") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("ArthurKun21") + name.set("Arthur") + email.set("16458204+ArthurKun21@users.noreply.github.com") + } + } + scm { + connection.set("scm:git:git://github.com/ArthurKun21/adam.git") + developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") + url.set("https://github.com/ArthurKun21/adam") + } + } } android { diff --git a/build.gradle.kts b/build.gradle.kts index fedf294c8..057913515 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,10 +1,16 @@ import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask +import org.gradle.api.publish.PublishingExtension import java.util.* plugins { alias(libs.plugins.gradle.versions) + alias(libs.plugins.vanniktech.maven.publish) apply false } +version = providers.environmentVariable("RELEASE_TAG") + .map { it.removePrefix("v") } + .getOrElse(libs.versions.adam.get()) + fun isNonStable(version: String): Boolean { val stableKeyword = listOf("RELEASE", "FINAL", "GA").any { version.uppercase(Locale.ENGLISH).contains(it) } val regex = "^[0-9,.v-]+(-r)?$".toRegex() @@ -17,3 +23,22 @@ tasks.withType { isNonStable(candidate.version) && !isNonStable(currentVersion) } } + +subprojects { + version = rootProject.version + + plugins.withId("com.vanniktech.maven.publish") { + configure { + repositories { + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/ArthurKun21/adam") + credentials { + username = System.getenv("GITHUB_ACTOR") + password = System.getenv("GITHUB_TOKEN") + } + } + } + } + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7b755dd16..64e1cf212 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -23,6 +23,7 @@ androidGradle = "9.0.0" testMonitor = "1.8.0" testRunner = "1.7.0" gradleVersionsPlugin = "0.53.0" +vanniktechMavenPublish = "0.36.0" dokka = "2.1.0" spotless = "8.2.1" @@ -68,3 +69,4 @@ dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } protobuf = { id = "com.google.protobuf", version.ref = "protobufGradle" } android-library = { id = "com.android.library", version.ref = "androidGradle" } gradle-versions = { id = "com.github.ben-manes.versions", version.ref = "gradleVersionsPlugin" } +vanniktech-maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "vanniktechMavenPublish" } diff --git a/server/server-stub-junit4/build.gradle.kts b/server/server-stub-junit4/build.gradle.kts index 897fe3d6c..f601f8184 100644 --- a/server/server-stub-junit4/build.gradle.kts +++ b/server/server-stub-junit4/build.gradle.kts @@ -17,6 +17,35 @@ plugins { id("adam.jvm") id("jacoco") + alias(libs.plugins.vanniktech.maven.publish) +} + +mavenPublishing { + coordinates("com.github.ArthurKun21", "server-stub-junit4", version.toString()) + + pom { + name.set("server-stub-junit4") + description.set("Android Debug Bridge helper - Server stub JUnit4") + url.set("https://github.com/ArthurKun21/adam") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("ArthurKun21") + name.set("Arthur") + email.set("16458204+ArthurKun21@users.noreply.github.com") + } + } + scm { + connection.set("scm:git:git://github.com/ArthurKun21/adam.git") + developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") + url.set("https://github.com/ArthurKun21/adam") + } + } } tasks.jacocoTestReport { diff --git a/server/server-stub-junit5/build.gradle.kts b/server/server-stub-junit5/build.gradle.kts index 931ea8a0d..973af5403 100644 --- a/server/server-stub-junit5/build.gradle.kts +++ b/server/server-stub-junit5/build.gradle.kts @@ -17,6 +17,35 @@ plugins { id("adam.jvm") id("jacoco") + alias(libs.plugins.vanniktech.maven.publish) +} + +mavenPublishing { + coordinates("com.github.ArthurKun21", "server-stub-junit5", version.toString()) + + pom { + name.set("server-stub-junit5") + description.set("Android Debug Bridge helper - Server stub JUnit5") + url.set("https://github.com/ArthurKun21/adam") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("ArthurKun21") + name.set("Arthur") + email.set("16458204+ArthurKun21@users.noreply.github.com") + } + } + scm { + connection.set("scm:git:git://github.com/ArthurKun21/adam.git") + developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") + url.set("https://github.com/ArthurKun21/adam") + } + } } tasks.jacocoTestReport { diff --git a/server/server-stub/build.gradle.kts b/server/server-stub/build.gradle.kts index 37fab2ab4..fde538aab 100644 --- a/server/server-stub/build.gradle.kts +++ b/server/server-stub/build.gradle.kts @@ -17,6 +17,35 @@ plugins { id("adam.jvm") id("jacoco") + alias(libs.plugins.vanniktech.maven.publish) +} + +mavenPublishing { + coordinates("com.github.ArthurKun21", "server-stub", version.toString()) + + pom { + name.set("server-stub") + description.set("Android Debug Bridge helper - Server stub") + url.set("https://github.com/ArthurKun21/adam") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("ArthurKun21") + name.set("Arthur") + email.set("16458204+ArthurKun21@users.noreply.github.com") + } + } + scm { + connection.set("scm:git:git://github.com/ArthurKun21/adam.git") + developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") + url.set("https://github.com/ArthurKun21/adam") + } + } } sourceSets { diff --git a/transport-ktor/build.gradle.kts b/transport-ktor/build.gradle.kts index bea56bbf9..746c54772 100644 --- a/transport-ktor/build.gradle.kts +++ b/transport-ktor/build.gradle.kts @@ -16,6 +16,35 @@ plugins { id("adam.jvm") + alias(libs.plugins.vanniktech.maven.publish) +} + +mavenPublishing { + coordinates("com.github.ArthurKun21", "transport-ktor", version.toString()) + + pom { + name.set("transport-ktor") + description.set("Android Debug Bridge helper - Ktor transport") + url.set("https://github.com/ArthurKun21/adam") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("ArthurKun21") + name.set("Arthur") + email.set("16458204+ArthurKun21@users.noreply.github.com") + } + } + scm { + connection.set("scm:git:git://github.com/ArthurKun21/adam.git") + developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") + url.set("https://github.com/ArthurKun21/adam") + } + } } dependencies { diff --git a/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocket.kt b/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocket.kt index f912d7e62..fdb62ff7e 100644 --- a/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocket.kt +++ b/transport-ktor/src/main/kotlin/com/malinskiy/adam/transport/ktor/KtorSocket.kt @@ -59,7 +59,9 @@ public class KtorSocket(private val ktorSocket: RealKtorSocket) : Socket { writeChannel.writeFully(byteArray, offset, offset + limit) } + @OptIn(io.ktor.utils.io.InternalAPI::class, kotlinx.io.InternalIoApi::class) override suspend fun readAvailable(buffer: ByteArray, offset: Int, limit: Int): Int { + if (!readChannel.isClosedForRead && readChannel.readBuffer.buffer.size == 0L) return 0 return readChannel.readAvailable(buffer, offset, limit) } From 8970d07204293d83c40a21b7024a889dd4b27b1d Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 04:02:10 +0000 Subject: [PATCH 16/50] tests: added regression tests for KtorSocket readFully and writeFully using byte arrays with offset and length parameters --- transport-ktor/build.gradle.kts | 4 + .../ktor/KtorSocketRegressionTest.kt | 109 ++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 transport-ktor/src/test/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketRegressionTest.kt diff --git a/transport-ktor/build.gradle.kts b/transport-ktor/build.gradle.kts index 746c54772..787819aa4 100644 --- a/transport-ktor/build.gradle.kts +++ b/transport-ktor/build.gradle.kts @@ -51,4 +51,8 @@ dependencies { implementation(project(":adam")) implementation(libs.ktor.network) implementation(libs.logcat) + + testImplementation(libs.junit4) + testImplementation(libs.assertk) + testImplementation(libs.coroutines.core) } diff --git a/transport-ktor/src/test/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketRegressionTest.kt b/transport-ktor/src/test/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketRegressionTest.kt new file mode 100644 index 000000000..b6b522a4f --- /dev/null +++ b/transport-ktor/src/test/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketRegressionTest.kt @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2021 Anton Malinskiy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.malinskiy.adam.transport.ktor + +import assertk.assertThat +import assertk.assertions.isEqualTo +import io.ktor.network.selector.SelectorManager +import io.ktor.network.sockets.aSocket +import io.ktor.network.sockets.openReadChannel +import io.ktor.network.sockets.openWriteChannel +import io.ktor.utils.io.readFully +import io.ktor.utils.io.writeFully +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withTimeout +import org.junit.Test + +public class KtorSocketRegressionTest { + + @Test + public fun readFullyUsesLimitAsLengthForByteArray(): Unit = runBlocking { + withTimeout(5_000) { + withSocketPair { clientSocket, serverSocket -> + val socket = KtorSocket(clientSocket) + try { + val expected = byteArrayOf(11, 22, 33, 44) + val writer = async { + serverSocket.openWriteChannel(autoFlush = true).writeFully(expected, 0, expected.size) + serverSocket.close() + } + + val target = ByteArray(10) + socket.readFully(target, 3, expected.size) + writer.await() + + assertThat(target.copyOfRange(0, 3).toList()).isEqualTo(byteArrayOf(0, 0, 0).toList()) + assertThat(target.copyOfRange(3, 7).toList()).isEqualTo(expected.toList()) + assertThat(target.copyOfRange(7, 10).toList()).isEqualTo(byteArrayOf(0, 0, 0).toList()) + } finally { + socket.close() + } + } + } + } + + @Test + public fun writeFullyUsesLimitAsLengthForByteArray(): Unit = runBlocking { + withTimeout(5_000) { + withSocketPair { clientSocket, serverSocket -> + val socket = KtorSocket(clientSocket) + try { + val source = byteArrayOf(7, 8, 9, 10, 11, 12) + val reader = async { + val buffer = ByteArray(3) + serverSocket.openReadChannel().readFully(buffer, 0, buffer.size) + buffer + } + + socket.writeFully(source, 2, 3) + + assertThat(reader.await().toList()).isEqualTo(byteArrayOf(9, 10, 11).toList()) + } finally { + socket.close() + } + } + } + } + + private suspend fun withSocketPair( + block: suspend ( + clientSocket: io.ktor.network.sockets.Socket, + serverSocket: io.ktor.network.sockets.Socket, + ) -> Unit, + ) { + val selector = SelectorManager(Dispatchers.IO) + val server = aSocket(selector).tcp().bind("127.0.0.1", 0) + try { + coroutineScope { + val accepted = async(Dispatchers.IO) { server.accept() } + val clientSocket = aSocket(selector).tcp().connect(server.localAddress) + val serverSocket = accepted.await() + try { + block(clientSocket, serverSocket) + } finally { + serverSocket.close() + } + } + } finally { + server.close() + selector.close() + } + } +} From 135e2e6ae4491570bba9eee8b7d8d4d5b42cc0e6 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 04:02:16 +0000 Subject: [PATCH 17/50] ci: update build command to include transport-ktor tests --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f1e8cef71..40dfcb02d 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -25,7 +25,7 @@ jobs: - uses: malinskiy/action-android/install-sdk@release/0.1.7 - name: build & test - run: ./gradlew assemble test jacocoTestReport + run: ./gradlew assemble test :transport-ktor:test jacocoTestReport - name: Publish Test Report uses: mikepenz/action-junit-report@v6 if: always() From aeb35eefd5f1718d346e6fa34b74a50f872a2244 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 04:02:21 +0000 Subject: [PATCH 18/50] docs: update AGENTS.md with Ktor transport regression test instructions --- AGENTS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index cc4dd4dbc..5f6406434 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,6 +5,8 @@ - Build: `./gradlew build` - Lint: `./gradlew spotlessCheck` (fix: `./gradlew spotlessApply`) - Run all tests: `./gradlew test` +- Run Ktor transport regression tests: `./gradlew :transport-ktor:test --tests "com.malinskiy.adam.transport.ktor.KtorSocketRegressionTest"` +- Purpose: guards Ktor byte-array offset/limit API semantics so Adam `Socket` methods keep length-based behavior during Ktor upgrades. - Run single test: `./gradlew :adam:test --tests "com.malinskiy.adam.ClassName.testMethod"` - Integration tests: `./gradlew :adam:integrationTest` From 9a5c5aa1980020e2bf6e680bc0908ff9e402a336 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 04:15:16 +0000 Subject: [PATCH 19/50] chore(gradle): centralize maven publishing configuration --- adam/build.gradle.kts | 31 +++--------------- .../build.gradle.kts | 25 +++------------ android-junit4/build.gradle.kts | 25 +++------------ android-testrunner-contract/build.gradle.kts | 28 +++------------- androidx-screencapture/build.gradle.kts | 25 +++------------ build.gradle.kts | 2 +- buildSrc/src/main/kotlin/adam.jvm.gradle.kts | 9 ++++++ .../kotlin/adam/buildlogic/MavenPomConfig.kt | 30 +++++++++++++++++ server/server-stub-junit4/build.gradle.kts | 32 +++---------------- server/server-stub-junit5/build.gradle.kts | 31 +++--------------- server/server-stub/build.gradle.kts | 32 +++---------------- transport-ktor/build.gradle.kts | 25 +++------------ 12 files changed, 84 insertions(+), 211 deletions(-) create mode 100644 buildSrc/src/main/kotlin/adam/buildlogic/MavenPomConfig.kt diff --git a/adam/build.gradle.kts b/adam/build.gradle.kts index 1c44ba5bd..be9dcceb3 100644 --- a/adam/build.gradle.kts +++ b/adam/build.gradle.kts @@ -1,3 +1,5 @@ +import adam.buildlogic.AdamPublishing +import adam.buildlogic.configureAdamPom import com.google.protobuf.gradle.id import com.google.protobuf.gradle.remove @@ -27,30 +29,12 @@ plugins { } mavenPublishing { - coordinates("com.github.ArthurKun21", "adam", version.toString()) + coordinates(AdamPublishing.GROUP, "adam", version.toString()) pom { name.set("adam") description.set("Android Debug Bridge helper - core library") - url.set("https://github.com/ArthurKun21/adam") - licenses { - license { - name.set("The Apache License, Version 2.0") - url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") - } - } - developers { - developer { - id.set("ArthurKun21") - name.set("Arthur") - email.set("16458204+ArthurKun21@users.noreply.github.com") - } - } - scm { - connection.set("scm:git:git://github.com/ArthurKun21/adam.git") - developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") - url.set("https://github.com/ArthurKun21/adam") - } + configureAdamPom() } } @@ -105,7 +89,6 @@ configurations["integrationTestRuntimeOnly"].extendsFrom(configurations.runtimeO fun DependencyHandler.`integrationTestImplementation`(dependencyNotation: Any): Dependency? = add("integrationTestImplementation", dependencyNotation) - val integrationTest = tasks.register("integrationTest") { description = "Runs integration tests" group = "verification" @@ -161,12 +144,6 @@ val jacocoCombinedTestReport = tasks.register("jacocoCombinedTestR mustRunAfter(tasks["test"], integrationTest) } -tasks.jacocoTestReport { - reports { - xml.required.set(true) - } -} - dokka { dokkaPublications.html { outputDirectory.set(rootProject.rootDir.resolve("docs/api")) diff --git a/android-junit4-test-annotation-producer/build.gradle.kts b/android-junit4-test-annotation-producer/build.gradle.kts index 58decd9d2..063ff20dc 100644 --- a/android-junit4-test-annotation-producer/build.gradle.kts +++ b/android-junit4-test-annotation-producer/build.gradle.kts @@ -1,3 +1,6 @@ +import adam.buildlogic.AdamPublishing +import adam.buildlogic.configureAdamPom + /* * Copyright (C) 2021 Anton Malinskiy * @@ -20,30 +23,12 @@ plugins { } mavenPublishing { - coordinates("com.github.ArthurKun21", "android-junit4-test-annotation-producer", version.toString()) + coordinates(AdamPublishing.GROUP, "android-junit4-test-annotation-producer", version.toString()) pom { name.set("android-junit4-test-annotation-producer") description.set("Android Debug Bridge helper - Test annotation producer") - url.set("https://github.com/ArthurKun21/adam") - licenses { - license { - name.set("The Apache License, Version 2.0") - url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") - } - } - developers { - developer { - id.set("ArthurKun21") - name.set("Arthur") - email.set("16458204+ArthurKun21@users.noreply.github.com") - } - } - scm { - connection.set("scm:git:git://github.com/ArthurKun21/adam.git") - developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") - url.set("https://github.com/ArthurKun21/adam") - } + configureAdamPom() } } diff --git a/android-junit4/build.gradle.kts b/android-junit4/build.gradle.kts index a0a441b91..a2e64e6f0 100644 --- a/android-junit4/build.gradle.kts +++ b/android-junit4/build.gradle.kts @@ -1,3 +1,6 @@ +import adam.buildlogic.AdamPublishing +import adam.buildlogic.configureAdamPom + /* * Copyright (C) 2021 Anton Malinskiy * @@ -20,30 +23,12 @@ plugins { } mavenPublishing { - coordinates("com.github.ArthurKun21", "android-junit4", version.toString()) + coordinates(AdamPublishing.GROUP, "android-junit4", version.toString()) pom { name.set("android-junit4") description.set("Android Debug Bridge helper - JUnit4 Android rules") - url.set("https://github.com/ArthurKun21/adam") - licenses { - license { - name.set("The Apache License, Version 2.0") - url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") - } - } - developers { - developer { - id.set("ArthurKun21") - name.set("Arthur") - email.set("16458204+ArthurKun21@users.noreply.github.com") - } - } - scm { - connection.set("scm:git:git://github.com/ArthurKun21/adam.git") - developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") - url.set("https://github.com/ArthurKun21/adam") - } + configureAdamPom() } } diff --git a/android-testrunner-contract/build.gradle.kts b/android-testrunner-contract/build.gradle.kts index 112528c08..29d96e0d9 100644 --- a/android-testrunner-contract/build.gradle.kts +++ b/android-testrunner-contract/build.gradle.kts @@ -1,4 +1,6 @@ +import adam.buildlogic.AdamPublishing import adam.buildlogic.ProjectConfig +import adam.buildlogic.configureAdamPom /* * Copyright (C) 2021 Anton Malinskiy @@ -22,30 +24,12 @@ plugins { } mavenPublishing { - coordinates("com.github.ArthurKun21", "android-testrunner-contract", version.toString()) + coordinates(AdamPublishing.GROUP, "android-testrunner-contract", version.toString()) pom { name.set("android-testrunner-contract") description.set("Android Debug Bridge helper - Test runner contract") - url.set("https://github.com/ArthurKun21/adam") - licenses { - license { - name.set("The Apache License, Version 2.0") - url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") - } - } - developers { - developer { - id.set("ArthurKun21") - name.set("Arthur") - email.set("16458204+ArthurKun21@users.noreply.github.com") - } - } - scm { - connection.set("scm:git:git://github.com/ArthurKun21/adam.git") - developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") - url.set("https://github.com/ArthurKun21/adam") - } + configureAdamPom() } } @@ -54,10 +38,8 @@ java { targetCompatibility = ProjectConfig.JavaVersion } -tasks.withType{ +tasks.withType { compilerOptions { jvmTarget.set(ProjectConfig.JvmTarget) } } - - diff --git a/androidx-screencapture/build.gradle.kts b/androidx-screencapture/build.gradle.kts index afab1ba0f..02f8bd452 100644 --- a/androidx-screencapture/build.gradle.kts +++ b/androidx-screencapture/build.gradle.kts @@ -1,3 +1,6 @@ +import adam.buildlogic.AdamPublishing +import adam.buildlogic.configureAdamPom + /* * Copyright (C) 2021 Anton Malinskiy * @@ -20,30 +23,12 @@ plugins { } mavenPublishing { - coordinates("com.github.ArthurKun21", "androidx-screencapture", version.toString()) + coordinates(AdamPublishing.GROUP, "androidx-screencapture", version.toString()) pom { name.set("androidx-screencapture") description.set("Android Debug Bridge helper - Screen capture support") - url.set("https://github.com/ArthurKun21/adam") - licenses { - license { - name.set("The Apache License, Version 2.0") - url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") - } - } - developers { - developer { - id.set("ArthurKun21") - name.set("Arthur") - email.set("16458204+ArthurKun21@users.noreply.github.com") - } - } - scm { - connection.set("scm:git:git://github.com/ArthurKun21/adam.git") - developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") - url.set("https://github.com/ArthurKun21/adam") - } + configureAdamPom() } } diff --git a/build.gradle.kts b/build.gradle.kts index 057913515..2d02a1cbc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,6 @@ import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask import org.gradle.api.publish.PublishingExtension -import java.util.* +import java.util.Locale plugins { alias(libs.plugins.gradle.versions) diff --git a/buildSrc/src/main/kotlin/adam.jvm.gradle.kts b/buildSrc/src/main/kotlin/adam.jvm.gradle.kts index 45c2c53d9..09855a11a 100644 --- a/buildSrc/src/main/kotlin/adam.jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/adam.jvm.gradle.kts @@ -1,4 +1,5 @@ import adam.buildlogic.ProjectConfig +import org.gradle.testing.jacoco.tasks.JacocoReport plugins { kotlin("jvm") @@ -23,3 +24,11 @@ tasks.withType{ ) } } + +pluginManager.withPlugin("jacoco") { + tasks.withType().configureEach { + reports { + xml.required.set(true) + } + } +} diff --git a/buildSrc/src/main/kotlin/adam/buildlogic/MavenPomConfig.kt b/buildSrc/src/main/kotlin/adam/buildlogic/MavenPomConfig.kt new file mode 100644 index 000000000..25d111d7f --- /dev/null +++ b/buildSrc/src/main/kotlin/adam/buildlogic/MavenPomConfig.kt @@ -0,0 +1,30 @@ +package adam.buildlogic + +import org.gradle.api.publish.maven.MavenPom + +object AdamPublishing { + const val GROUP = "com.github.ArthurKun21" + const val REPOSITORY_URL = "https://github.com/ArthurKun21/adam" +} + +fun MavenPom.configureAdamPom() { + url.set(AdamPublishing.REPOSITORY_URL) + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("ArthurKun21") + name.set("Arthur") + email.set("16458204+ArthurKun21@users.noreply.github.com") + } + } + scm { + connection.set("scm:git:git://github.com/ArthurKun21/adam.git") + developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") + url.set(AdamPublishing.REPOSITORY_URL) + } +} diff --git a/server/server-stub-junit4/build.gradle.kts b/server/server-stub-junit4/build.gradle.kts index f601f8184..5f0e3fa83 100644 --- a/server/server-stub-junit4/build.gradle.kts +++ b/server/server-stub-junit4/build.gradle.kts @@ -1,3 +1,6 @@ +import adam.buildlogic.AdamPublishing +import adam.buildlogic.configureAdamPom + /* * Copyright (C) 2021 Anton Malinskiy * @@ -21,40 +24,15 @@ plugins { } mavenPublishing { - coordinates("com.github.ArthurKun21", "server-stub-junit4", version.toString()) + coordinates(AdamPublishing.GROUP, "server-stub-junit4", version.toString()) pom { name.set("server-stub-junit4") description.set("Android Debug Bridge helper - Server stub JUnit4") - url.set("https://github.com/ArthurKun21/adam") - licenses { - license { - name.set("The Apache License, Version 2.0") - url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") - } - } - developers { - developer { - id.set("ArthurKun21") - name.set("Arthur") - email.set("16458204+ArthurKun21@users.noreply.github.com") - } - } - scm { - connection.set("scm:git:git://github.com/ArthurKun21/adam.git") - developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") - url.set("https://github.com/ArthurKun21/adam") - } + configureAdamPom() } } -tasks.jacocoTestReport { - reports { - xml.required.set(true) - } -} - - dependencies { api(project(":server:server-stub")) implementation(libs.junit4) diff --git a/server/server-stub-junit5/build.gradle.kts b/server/server-stub-junit5/build.gradle.kts index 973af5403..387483ec3 100644 --- a/server/server-stub-junit5/build.gradle.kts +++ b/server/server-stub-junit5/build.gradle.kts @@ -1,3 +1,6 @@ +import adam.buildlogic.AdamPublishing +import adam.buildlogic.configureAdamPom + /* * Copyright (C) 2021 Anton Malinskiy * @@ -21,36 +24,12 @@ plugins { } mavenPublishing { - coordinates("com.github.ArthurKun21", "server-stub-junit5", version.toString()) + coordinates(AdamPublishing.GROUP, "server-stub-junit5", version.toString()) pom { name.set("server-stub-junit5") description.set("Android Debug Bridge helper - Server stub JUnit5") - url.set("https://github.com/ArthurKun21/adam") - licenses { - license { - name.set("The Apache License, Version 2.0") - url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") - } - } - developers { - developer { - id.set("ArthurKun21") - name.set("Arthur") - email.set("16458204+ArthurKun21@users.noreply.github.com") - } - } - scm { - connection.set("scm:git:git://github.com/ArthurKun21/adam.git") - developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") - url.set("https://github.com/ArthurKun21/adam") - } - } -} - -tasks.jacocoTestReport { - reports { - xml.required.set(true) + configureAdamPom() } } diff --git a/server/server-stub/build.gradle.kts b/server/server-stub/build.gradle.kts index fde538aab..ad049d44b 100644 --- a/server/server-stub/build.gradle.kts +++ b/server/server-stub/build.gradle.kts @@ -1,3 +1,6 @@ +import adam.buildlogic.AdamPublishing +import adam.buildlogic.configureAdamPom + /* * Copyright (C) 2021 Anton Malinskiy * @@ -21,30 +24,12 @@ plugins { } mavenPublishing { - coordinates("com.github.ArthurKun21", "server-stub", version.toString()) + coordinates(AdamPublishing.GROUP, "server-stub", version.toString()) pom { name.set("server-stub") description.set("Android Debug Bridge helper - Server stub") - url.set("https://github.com/ArthurKun21/adam") - licenses { - license { - name.set("The Apache License, Version 2.0") - url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") - } - } - developers { - developer { - id.set("ArthurKun21") - name.set("Arthur") - email.set("16458204+ArthurKun21@users.noreply.github.com") - } - } - scm { - connection.set("scm:git:git://github.com/ArthurKun21/adam.git") - developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") - url.set("https://github.com/ArthurKun21/adam") - } + configureAdamPom() } } @@ -94,13 +79,6 @@ val jacocoIntegrationTestReport = tasks.register("jacocoIntegratio } tasks.check { dependsOn(integrationTest, jacocoIntegrationTestReport) } -tasks.jacocoTestReport { - reports { - xml.required.set(true) - } -} - - dependencies { implementation(kotlin("stdlib-jdk8")) implementation(libs.coroutines.core) diff --git a/transport-ktor/build.gradle.kts b/transport-ktor/build.gradle.kts index 787819aa4..0320da592 100644 --- a/transport-ktor/build.gradle.kts +++ b/transport-ktor/build.gradle.kts @@ -1,3 +1,6 @@ +import adam.buildlogic.AdamPublishing +import adam.buildlogic.configureAdamPom + /* * Copyright (C) 2021 Anton Malinskiy * @@ -20,30 +23,12 @@ plugins { } mavenPublishing { - coordinates("com.github.ArthurKun21", "transport-ktor", version.toString()) + coordinates(AdamPublishing.GROUP, "transport-ktor", version.toString()) pom { name.set("transport-ktor") description.set("Android Debug Bridge helper - Ktor transport") - url.set("https://github.com/ArthurKun21/adam") - licenses { - license { - name.set("The Apache License, Version 2.0") - url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") - } - } - developers { - developer { - id.set("ArthurKun21") - name.set("Arthur") - email.set("16458204+ArthurKun21@users.noreply.github.com") - } - } - scm { - connection.set("scm:git:git://github.com/ArthurKun21/adam.git") - developerConnection.set("scm:git:ssh://github.com/ArthurKun21/adam.git") - url.set("https://github.com/ArthurKun21/adam") - } + configureAdamPom() } } From 703f8bbe82c62fe5f108e7540037b67778235d24 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 04:21:52 +0000 Subject: [PATCH 20/50] chore: refactor integration test configuration to use centralized setup --- adam/build.gradle.kts | 18 ++--------- .../adam/buildlogic/IntegrationTestConfig.kt | 32 +++++++++++++++++++ server/server-stub/build.gradle.kts | 19 ++--------- 3 files changed, 38 insertions(+), 31 deletions(-) create mode 100644 buildSrc/src/main/kotlin/adam/buildlogic/IntegrationTestConfig.kt diff --git a/adam/build.gradle.kts b/adam/build.gradle.kts index be9dcceb3..c85030f30 100644 --- a/adam/build.gradle.kts +++ b/adam/build.gradle.kts @@ -1,5 +1,7 @@ import adam.buildlogic.AdamPublishing +import adam.buildlogic.configureIntegrationTestSourceSet import adam.buildlogic.configureAdamPom +import adam.buildlogic.integrationTestImplementation import com.google.protobuf.gradle.id import com.google.protobuf.gradle.remove @@ -73,21 +75,7 @@ protobuf { } } -sourceSets { - create("integrationTest") { - compileClasspath += sourceSets.main.get().output - runtimeClasspath += sourceSets.main.get().output - } -} - -val integrationTestImplementation: Configuration by configurations.getting { - extendsFrom(configurations.implementation.get()) -} - -configurations["integrationTestRuntimeOnly"].extendsFrom(configurations.runtimeOnly.get()) - -fun DependencyHandler.`integrationTestImplementation`(dependencyNotation: Any): Dependency? = - add("integrationTestImplementation", dependencyNotation) +configureIntegrationTestSourceSet() val integrationTest = tasks.register("integrationTest") { description = "Runs integration tests" diff --git a/buildSrc/src/main/kotlin/adam/buildlogic/IntegrationTestConfig.kt b/buildSrc/src/main/kotlin/adam/buildlogic/IntegrationTestConfig.kt new file mode 100644 index 000000000..72e0cc489 --- /dev/null +++ b/buildSrc/src/main/kotlin/adam/buildlogic/IntegrationTestConfig.kt @@ -0,0 +1,32 @@ +package adam.buildlogic + +import org.gradle.api.Project +import org.gradle.api.artifacts.ConfigurationContainer +import org.gradle.api.artifacts.Dependency +import org.gradle.api.artifacts.dsl.DependencyHandler +import org.gradle.api.tasks.SourceSetContainer +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.getByName + +private const val INTEGRATION_TEST = "integrationTest" +private const val INTEGRATION_TEST_IMPLEMENTATION = "integrationTestImplementation" +private const val INTEGRATION_TEST_RUNTIME_ONLY = "integrationTestRuntimeOnly" + +fun Project.configureIntegrationTestSourceSet() { + extensions.configure { + create(INTEGRATION_TEST) { + compileClasspath += getByName("main").output + runtimeClasspath += getByName("main").output + } + } + + configurations.configureIntegrationTestConfigurations() +} + +fun DependencyHandler.integrationTestImplementation(dependencyNotation: Any): Dependency? = + add(INTEGRATION_TEST_IMPLEMENTATION, dependencyNotation) + +private fun ConfigurationContainer.configureIntegrationTestConfigurations() { + getByName(INTEGRATION_TEST_IMPLEMENTATION).extendsFrom(getByName("implementation")) + getByName(INTEGRATION_TEST_RUNTIME_ONLY).extendsFrom(getByName("runtimeOnly")) +} diff --git a/server/server-stub/build.gradle.kts b/server/server-stub/build.gradle.kts index ad049d44b..2207d4dc3 100644 --- a/server/server-stub/build.gradle.kts +++ b/server/server-stub/build.gradle.kts @@ -1,5 +1,7 @@ import adam.buildlogic.AdamPublishing +import adam.buildlogic.configureIntegrationTestSourceSet import adam.buildlogic.configureAdamPom +import adam.buildlogic.integrationTestImplementation /* * Copyright (C) 2021 Anton Malinskiy @@ -33,22 +35,7 @@ mavenPublishing { } } -sourceSets { - create("integrationTest") { - compileClasspath += sourceSets.main.get().output - runtimeClasspath += sourceSets.main.get().output - } -} - -val integrationTestImplementation: Configuration by configurations.getting { - extendsFrom(configurations.implementation.get()) -} - -configurations["integrationTestRuntimeOnly"].extendsFrom(configurations.runtimeOnly.get()) - -fun DependencyHandler.`integrationTestImplementation`(dependencyNotation: Any): Dependency? = - add("integrationTestImplementation", dependencyNotation) - +configureIntegrationTestSourceSet() val integrationTest = tasks.register("integrationTest") { description = "Runs integration tests" From 55263485f68736aad953913d85c5fb0a2bda7c81 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 04:26:42 +0000 Subject: [PATCH 21/50] chore: refactor integration test configuration to use centralized tasks --- adam/build.gradle.kts | 41 +++++--------- .../adam/buildlogic/IntegrationTestConfig.kt | 55 +++++++++++++++++++ server/server-stub/build.gradle.kts | 31 +++-------- 3 files changed, 78 insertions(+), 49 deletions(-) diff --git a/adam/build.gradle.kts b/adam/build.gradle.kts index c85030f30..ea4ba22b1 100644 --- a/adam/build.gradle.kts +++ b/adam/build.gradle.kts @@ -1,5 +1,6 @@ import adam.buildlogic.AdamPublishing import adam.buildlogic.configureIntegrationTestSourceSet +import adam.buildlogic.configureIntegrationTestTasks import adam.buildlogic.configureAdamPom import adam.buildlogic.integrationTestImplementation import com.google.protobuf.gradle.id @@ -77,22 +78,24 @@ protobuf { configureIntegrationTestSourceSet() -val integrationTest = tasks.register("integrationTest") { - description = "Runs integration tests" - group = "verification" +val integrationTestTasks = configureIntegrationTestTasks( + configureIntegrationTest = { jacocoIntegrationTestReport -> + finalizedBy(jacocoIntegrationTestReport) + }, + configureJacocoReport = { integrationTest -> + executionData(fileTree(layout.buildDirectory).include("jacoco/integrationTest.exec")) + mustRunAfter(integrationTest) + }, +) - testClassesDirs = sourceSets["integrationTest"].output.classesDirs - classpath = sourceSets["integrationTest"].runtimeClasspath - shouldRunAfter("test") +val integrationTest = integrationTestTasks.integrationTest - jacoco { - include("**") +val jacocoIntegrationTestReport = integrationTestTasks.jacocoIntegrationTestReport +jacocoIntegrationTestReport.configure { + reports { + xml.required.set(true) } } -integrationTest.configure { - outputs.upToDateWhen { false } - finalizedBy("jacocoIntegrationTestReport") -} // See https://github.com/jacoco/jacoco/issues/1357 tasks.withType { @@ -108,20 +111,6 @@ val connectedAndroidTest = tasks.register("connectedAndroidTest") { dependsOn(integrationTest) } -val jacocoIntegrationTestReport = tasks.register("jacocoIntegrationTestReport") { - description = "Generates code coverage report for integrationTest task" - group = "verification" - reports { - xml.required.set(true) - } - - executionData(fileTree(layout.buildDirectory).include("jacoco/integrationTest.exec")) - sourceSets(sourceSets.getByName("integrationTest")) - classDirectories.setFrom(sourceSets.getByName("main").output.classesDirs) - mustRunAfter(integrationTest) -} -tasks.check { dependsOn(integrationTest, jacocoIntegrationTestReport) } - val jacocoCombinedTestReport = tasks.register("jacocoCombinedTestReport") { description = "Generates code coverage report for all test tasks" group = "verification" diff --git a/buildSrc/src/main/kotlin/adam/buildlogic/IntegrationTestConfig.kt b/buildSrc/src/main/kotlin/adam/buildlogic/IntegrationTestConfig.kt index 72e0cc489..6d02ecfaf 100644 --- a/buildSrc/src/main/kotlin/adam/buildlogic/IntegrationTestConfig.kt +++ b/buildSrc/src/main/kotlin/adam/buildlogic/IntegrationTestConfig.kt @@ -4,13 +4,20 @@ import org.gradle.api.Project import org.gradle.api.artifacts.ConfigurationContainer import org.gradle.api.artifacts.Dependency import org.gradle.api.artifacts.dsl.DependencyHandler +import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.SourceSetContainer +import org.gradle.api.tasks.testing.Test +import org.gradle.testing.jacoco.plugins.JacocoTaskExtension +import org.gradle.testing.jacoco.tasks.JacocoReport import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.getByName +import org.gradle.kotlin.dsl.named +import org.gradle.kotlin.dsl.register private const val INTEGRATION_TEST = "integrationTest" private const val INTEGRATION_TEST_IMPLEMENTATION = "integrationTestImplementation" private const val INTEGRATION_TEST_RUNTIME_ONLY = "integrationTestRuntimeOnly" +private const val JACOCO_INTEGRATION_TEST_REPORT = "jacocoIntegrationTestReport" fun Project.configureIntegrationTestSourceSet() { extensions.configure { @@ -26,6 +33,54 @@ fun Project.configureIntegrationTestSourceSet() { fun DependencyHandler.integrationTestImplementation(dependencyNotation: Any): Dependency? = add(INTEGRATION_TEST_IMPLEMENTATION, dependencyNotation) +data class IntegrationTestTasks( + val integrationTest: TaskProvider, + val jacocoIntegrationTestReport: TaskProvider, +) + +fun Project.configureIntegrationTestTasks( + configureIntegrationTest: Test.(TaskProvider) -> Unit = {}, + configureJacocoReport: JacocoReport.(TaskProvider) -> Unit = {}, +): IntegrationTestTasks { + val sourceSets = extensions.getByType(SourceSetContainer::class.java) + + val integrationTest = tasks.register(INTEGRATION_TEST) { + description = "Runs integration tests" + group = "verification" + + testClassesDirs = sourceSets.getByName(INTEGRATION_TEST).output.classesDirs + classpath = sourceSets.getByName(INTEGRATION_TEST).runtimeClasspath + shouldRunAfter("test") + + extensions.configure(JacocoTaskExtension::class.java) { + includes = listOf("**") + } + } + + val jacocoIntegrationTestReport = tasks.register(JACOCO_INTEGRATION_TEST_REPORT) { + description = "Generates code coverage report for integrationTest task" + group = "verification" + + sourceSets(sourceSets.getByName(INTEGRATION_TEST)) + classDirectories.setFrom(sourceSets.getByName("main").output.classesDirs) + } + + integrationTest.configure { + outputs.upToDateWhen { false } + configureIntegrationTest(jacocoIntegrationTestReport) + } + + jacocoIntegrationTestReport.configure { + configureJacocoReport(integrationTest) + } + + tasks.named("check") { + dependsOn(integrationTest, jacocoIntegrationTestReport) + } + + return IntegrationTestTasks(integrationTest, jacocoIntegrationTestReport) +} + private fun ConfigurationContainer.configureIntegrationTestConfigurations() { getByName(INTEGRATION_TEST_IMPLEMENTATION).extendsFrom(getByName("implementation")) getByName(INTEGRATION_TEST_RUNTIME_ONLY).extendsFrom(getByName("runtimeOnly")) diff --git a/server/server-stub/build.gradle.kts b/server/server-stub/build.gradle.kts index 2207d4dc3..0e4b1394b 100644 --- a/server/server-stub/build.gradle.kts +++ b/server/server-stub/build.gradle.kts @@ -1,5 +1,6 @@ import adam.buildlogic.AdamPublishing import adam.buildlogic.configureIntegrationTestSourceSet +import adam.buildlogic.configureIntegrationTestTasks import adam.buildlogic.configureAdamPom import adam.buildlogic.integrationTestImplementation @@ -37,34 +38,18 @@ mavenPublishing { configureIntegrationTestSourceSet() -val integrationTest = tasks.register("integrationTest") { - description = "Runs integration tests" - group = "verification" +val integrationTestTasks = configureIntegrationTestTasks( + configureJacocoReport = { integrationTest -> + executionData(integrationTest) + }, +) - testClassesDirs = sourceSets["integrationTest"].output.classesDirs - classpath = sourceSets["integrationTest"].runtimeClasspath - shouldRunAfter("test") - - jacoco { - include("**") - } -} -integrationTest.configure { - outputs.upToDateWhen { false } -} - -val jacocoIntegrationTestReport = tasks.register("jacocoIntegrationTestReport") { - description = "Generates code coverage report for integrationTest task" - group = "verification" +val jacocoIntegrationTestReport = integrationTestTasks.jacocoIntegrationTestReport +jacocoIntegrationTestReport.configure { reports { xml.required.set(true) } - - executionData(integrationTest) - sourceSets(sourceSets.getByName("integrationTest")) - classDirectories.setFrom(sourceSets.getByName("main").output.classesDirs) } -tasks.check { dependsOn(integrationTest, jacocoIntegrationTestReport) } dependencies { implementation(kotlin("stdlib-jdk8")) From 827eb11c2b5abe82d2fd146d3e1e1fa3825a1f18 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 04:27:20 +0000 Subject: [PATCH 22/50] chore: enable spotless --- android-testrunner-contract/build.gradle.kts | 1 + buildSrc/src/main/kotlin/adam.android.library.gradle.kts | 2 +- buildSrc/src/main/kotlin/adam.jvm.gradle.kts | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/android-testrunner-contract/build.gradle.kts b/android-testrunner-contract/build.gradle.kts index 29d96e0d9..102b74672 100644 --- a/android-testrunner-contract/build.gradle.kts +++ b/android-testrunner-contract/build.gradle.kts @@ -21,6 +21,7 @@ import adam.buildlogic.configureAdamPom plugins { id("java") alias(libs.plugins.vanniktech.maven.publish) + id("adam.code.lint") } mavenPublishing { diff --git a/buildSrc/src/main/kotlin/adam.android.library.gradle.kts b/buildSrc/src/main/kotlin/adam.android.library.gradle.kts index 3b0dccef2..47b4986d8 100644 --- a/buildSrc/src/main/kotlin/adam.android.library.gradle.kts +++ b/buildSrc/src/main/kotlin/adam.android.library.gradle.kts @@ -4,7 +4,7 @@ import org.gradle.accessors.dm.LibrariesForLibs plugins { id("com.android.library") - // id("adam.code.lint") + id("adam.code.lint") } kotlin { diff --git a/buildSrc/src/main/kotlin/adam.jvm.gradle.kts b/buildSrc/src/main/kotlin/adam.jvm.gradle.kts index 09855a11a..86d3e6a4f 100644 --- a/buildSrc/src/main/kotlin/adam.jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/adam.jvm.gradle.kts @@ -3,7 +3,7 @@ import org.gradle.testing.jacoco.tasks.JacocoReport plugins { kotlin("jvm") - // id("adam.code.lint") + id("adam.code.lint") } kotlin { From 391bc853d08b6419d18d352ddcdcdfcfd0f52d11 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 04:33:20 +0000 Subject: [PATCH 23/50] chore: apply spotless --- adam/build.gradle.kts | 2 +- .../InstrumentationResponseTransformerTest.kt | 6 +- .../adam/server/junit4/AdbServerRule.kt | 1 - .../adam/server/junit5/AdbServerExtension.kt | 12 ++-- server/server-stub/build.gradle.kts | 2 +- .../server/stub/AndroidDebugBridgeServer.kt | 1 - .../adam/server/stub/ConsoleReadChannel.kt | 4 +- .../adam/server/stub/EmulatorConsoleServer.kt | 4 +- .../adam/server/stub/ServerReadChannel.kt | 70 ++++++++++++------- .../adam/server/stub/ServerWriteChannel.kt | 6 +- .../malinskiy/adam/server/stub/StubSocket.kt | 2 +- .../adam/server/stub/dsl/DeviceExpectation.kt | 2 +- .../adam/server/stub/dsl/Expectation.kt | 6 +- .../malinskiy/adam/server/stub/dsl/Session.kt | 14 ++-- .../ktor/KtorSocketRegressionTest.kt | 2 +- 15 files changed, 80 insertions(+), 54 deletions(-) diff --git a/adam/build.gradle.kts b/adam/build.gradle.kts index ea4ba22b1..79b75f459 100644 --- a/adam/build.gradle.kts +++ b/adam/build.gradle.kts @@ -1,7 +1,7 @@ import adam.buildlogic.AdamPublishing +import adam.buildlogic.configureAdamPom import adam.buildlogic.configureIntegrationTestSourceSet import adam.buildlogic.configureIntegrationTestTasks -import adam.buildlogic.configureAdamPom import adam.buildlogic.integrationTestImplementation import com.google.protobuf.gradle.id import com.google.protobuf.gradle.remove diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformerTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformerTest.kt index d027981e3..61c958b75 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformerTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformerTest.kt @@ -168,8 +168,10 @@ class InstrumentationResponseTransformerTest { fun testBufferFraming() = runBlocking { val transformer = InstrumentationResponseTransformer() - val lines = javaClass.getResourceAsStream( - "/instrumentation/log_6.input").reader().readLines() + val lines = javaClass + .getResourceAsStream("/instrumentation/log_6.input") + .reader() + .readLines() val events = mutableListOf() for (line in lines) { diff --git a/server/server-stub-junit4/src/main/kotlin/com/malinskiy/adam/server/junit4/AdbServerRule.kt b/server/server-stub-junit4/src/main/kotlin/com/malinskiy/adam/server/junit4/AdbServerRule.kt index d2bd61150..1eceed60e 100644 --- a/server/server-stub-junit4/src/main/kotlin/com/malinskiy/adam/server/junit4/AdbServerRule.kt +++ b/server/server-stub-junit4/src/main/kotlin/com/malinskiy/adam/server/junit4/AdbServerRule.kt @@ -54,4 +54,3 @@ public class AdbServerRule : TestRule { server.session(block) } } - diff --git a/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbServerExtension.kt b/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbServerExtension.kt index d7ed4056c..3c1eaf9f3 100644 --- a/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbServerExtension.kt +++ b/server/server-stub-junit5/src/main/kotlin/com/malinskiy/adam/server/junit5/AdbServerExtension.kt @@ -31,7 +31,6 @@ import kotlin.reflect.full.hasAnnotation import kotlin.reflect.full.isSubtypeOf import kotlin.reflect.full.memberProperties - public class AdbServerExtension : BeforeEachCallback, AfterEachCallback { public lateinit var server: AndroidDebugBridgeServer public val client: AndroidDebugBridgeClient @@ -55,7 +54,10 @@ public class AdbServerExtension : BeforeEachCallback, AfterEachCallback { private fun setupServerField(context: ExtensionContext) { val instance = context.testInstance.get() instance::class.memberProperties - .filter { it.hasAnnotation() && it.returnType.isSubtypeOf(AndroidDebugBridgeServer::class.createType()) } + .filter { + it.hasAnnotation() && + it.returnType.isSubtypeOf(AndroidDebugBridgeServer::class.createType()) + } .filterIsInstance>() .forEach { prop -> prop.setter.call(instance, server) @@ -65,7 +67,10 @@ public class AdbServerExtension : BeforeEachCallback, AfterEachCallback { private fun setupClientField(context: ExtensionContext) { val instance = context.testInstance.get() instance::class.memberProperties - .filter { it.hasAnnotation() && it.returnType.isSubtypeOf(AndroidDebugBridgeClient::class.createType()) } + .filter { + it.hasAnnotation() && + it.returnType.isSubtypeOf(AndroidDebugBridgeClient::class.createType()) + } .filterIsInstance>() .forEach { prop -> prop.setter.call(instance, client) @@ -80,4 +85,3 @@ public class AdbServerExtension : BeforeEachCallback, AfterEachCallback { } } } - diff --git a/server/server-stub/build.gradle.kts b/server/server-stub/build.gradle.kts index 0e4b1394b..082015ba1 100644 --- a/server/server-stub/build.gradle.kts +++ b/server/server-stub/build.gradle.kts @@ -1,7 +1,7 @@ import adam.buildlogic.AdamPublishing +import adam.buildlogic.configureAdamPom import adam.buildlogic.configureIntegrationTestSourceSet import adam.buildlogic.configureIntegrationTestTasks -import adam.buildlogic.configureAdamPom import adam.buildlogic.integrationTestImplementation /* diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/AndroidDebugBridgeServer.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/AndroidDebugBridgeServer.kt index ef8a5f483..5a339de4c 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/AndroidDebugBridgeServer.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/AndroidDebugBridgeServer.kt @@ -40,7 +40,6 @@ import kotlinx.coroutines.newFixedThreadPoolContext import kotlinx.coroutines.runBlocking import kotlin.coroutines.CoroutineContext - public class AndroidDebugBridgeServer : CoroutineScope { private val executionDispatcher by lazy { newFixedThreadPoolContext(4, "AndroidDebugBridgeServer") diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ConsoleReadChannel.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ConsoleReadChannel.kt index 9e652e384..fae3a10cc 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ConsoleReadChannel.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ConsoleReadChannel.kt @@ -24,6 +24,8 @@ import io.ktor.utils.io.readLine public class ConsoleReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel by delegate { public suspend fun receiveCommand(): String = delegate.readLine()!! - public suspend fun receiveAuth(): String = receiveCommand().apply { assertThat(this).startsWith("auth ") }.substringAfter("auth ") + public suspend fun receiveAuth(): String = receiveCommand().apply { + assertThat(this).startsWith("auth ") + }.substringAfter("auth ") public suspend fun receiveExit(): String = receiveCommand().apply { assertThat(this).isEqualTo("quit") } } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/EmulatorConsoleServer.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/EmulatorConsoleServer.kt index 545fadebe..ca7d298b4 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/EmulatorConsoleServer.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/EmulatorConsoleServer.kt @@ -49,7 +49,9 @@ public class EmulatorConsoleServer : CoroutineScope, Closeable { private val job = SupervisorJob() public var port: Int = 0 - public suspend fun startAndListen(block: suspend (ConsoleReadChannel, ConsoleWriteChannel) -> Unit): Pair { + public suspend fun startAndListen( + block: suspend (ConsoleReadChannel, ConsoleWriteChannel) -> Unit, + ): Pair { val address = InetSocketAddress("127.0.0.1", port) val server = aSocket(SelectorManager(Dispatchers.IO)).tcp().bind(address) port = server.localAddress.toJavaAddress().port diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerReadChannel.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerReadChannel.kt index 5d038656d..5d3a681b1 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerReadChannel.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerReadChannel.kt @@ -27,11 +27,11 @@ import io.ktor.util.cio.writeChannel import io.ktor.utils.io.ByteReadChannel import io.ktor.utils.io.readFully import io.ktor.utils.io.writeFully -import io.ktor.utils.io.readByte as channelReadByte -import io.ktor.utils.io.readInt as channelReadInt import kotlinx.coroutines.Job import java.io.File import kotlin.coroutines.coroutineContext +import io.ktor.utils.io.readByte as channelReadByte +import io.ktor.utils.io.readInt as channelReadInt public class ServerReadChannel(private val delegate: ByteReadChannel) : ByteReadChannel by delegate { @@ -60,9 +60,11 @@ public class ServerReadChannel(private val delegate: ByteReadChannel) : ByteRead public suspend fun receiveStat(): String { val protocolMessage = receiveProtocolMessage() val message = String(protocolMessage, Const.DEFAULT_TRANSPORT_ENCODING) - if (message != "STAT") throw RuntimeException( - "Unexpected protocol message $message" - ) + if (message != "STAT") { + throw RuntimeException( + "Unexpected protocol message $message", + ) + } val size = readIntLittleEndian() val request = ByteArray(size) readFully(request, 0, size) @@ -72,9 +74,11 @@ public class ServerReadChannel(private val delegate: ByteReadChannel) : ByteRead public suspend fun receiveStatV2(): String { val protocolMessage = receiveProtocolMessage() val message = String(protocolMessage, Const.DEFAULT_TRANSPORT_ENCODING) - if (message != "LST2") throw RuntimeException( - "Unexpected protocol message $message" - ) + if (message != "LST2") { + throw RuntimeException( + "Unexpected protocol message $message", + ) + } val size = readIntLittleEndian() val request = ByteArray(size) readFully(request, 0, size) @@ -84,9 +88,11 @@ public class ServerReadChannel(private val delegate: ByteReadChannel) : ByteRead public suspend fun receiveList(): String { val protocolMessage = receiveProtocolMessage() val message = String(protocolMessage, Const.DEFAULT_TRANSPORT_ENCODING) - if (message != "LIST") throw RuntimeException( - "Unexpected protocol message $message" - ) + if (message != "LIST") { + throw RuntimeException( + "Unexpected protocol message $message", + ) + } val size = readIntLittleEndian() val request = ByteArray(size) readFully(request, 0, size) @@ -96,9 +102,11 @@ public class ServerReadChannel(private val delegate: ByteReadChannel) : ByteRead public suspend fun receiveListV2(): String { val protocolMessage = receiveProtocolMessage() val message = String(protocolMessage, Const.DEFAULT_TRANSPORT_ENCODING) - if (message != "LIS2") throw RuntimeException( - "Unexpected protocol message $message" - ) + if (message != "LIS2") { + throw RuntimeException( + "Unexpected protocol message $message", + ) + } val size = readIntLittleEndian() val request = ByteArray(size) readFully(request, 0, size) @@ -108,9 +116,11 @@ public class ServerReadChannel(private val delegate: ByteReadChannel) : ByteRead public suspend fun receiveSend(): String { val protocolMessage = receiveProtocolMessage() val message = String(protocolMessage, Const.DEFAULT_TRANSPORT_ENCODING) - if (message != "SEND") throw RuntimeException( - "Unexpected protocol message $message" - ) + if (message != "SEND") { + throw RuntimeException( + "Unexpected protocol message $message", + ) + } val size = readIntLittleEndian() val request = ByteArray(size) readFully(request, 0, size) @@ -120,17 +130,21 @@ public class ServerReadChannel(private val delegate: ByteReadChannel) : ByteRead public suspend fun receiveSendV2(): Triple { val protocolMessage = receiveProtocolMessage() var message = String(protocolMessage, Const.DEFAULT_TRANSPORT_ENCODING) - if (message != "SND2") throw RuntimeException( - "Unexpected protocol message $message" - ) + if (message != "SND2") { + throw RuntimeException( + "Unexpected protocol message $message", + ) + } val size = readIntLittleEndian() val request = ByteArray(size) readFully(request, 0, size) message = String(receiveProtocolMessage(), Const.DEFAULT_TRANSPORT_ENCODING) - if (message != "SND2") throw RuntimeException( - "Unexpected protocol message $message" - ) + if (message != "SND2") { + throw RuntimeException( + "Unexpected protocol message $message", + ) + } val mode = readIntLittleEndian() val flags = readIntLittleEndian() return Triple(String(request, Const.DEFAULT_TRANSPORT_ENCODING), mode, flags) @@ -145,9 +159,11 @@ public class ServerReadChannel(private val delegate: ByteReadChannel) : ByteRead public suspend fun receiveRecv(): String { val protocolMessage = receiveProtocolMessage() val message = String(protocolMessage, Const.DEFAULT_TRANSPORT_ENCODING) - if (message != "RECV") throw RuntimeException( - "Unexpected protocol message $message" - ) + if (message != "RECV") { + throw RuntimeException( + "Unexpected protocol message $message", + ) + } val size = readIntLittleEndian() val request = ByteArray(size) @@ -190,6 +206,7 @@ public class ServerReadChannel(private val delegate: ByteReadChannel) : ByteRead channel.flushAndClose() return file } + header.contentEquals(Const.Message.DATA) -> { val available = headerBuffer.copyOfRange(4, 8).toInt() if (available > Const.MAX_FILE_PACKET_LENGTH) { @@ -198,6 +215,7 @@ public class ServerReadChannel(private val delegate: ByteReadChannel) : ByteRead readFully(dataBuffer, 0, available) channel.writeFully(dataBuffer, 0, available) } + else -> throw RuntimeException("Something bad happened") } } diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerWriteChannel.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerWriteChannel.kt index a64078638..365f02161 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerWriteChannel.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/ServerWriteChannel.kt @@ -22,9 +22,9 @@ import io.ktor.utils.io.ByteWriteChannel import io.ktor.utils.io.writeFully import io.ktor.utils.io.writeStringUtf8 import java.nio.ByteBuffer +import io.ktor.utils.io.writeByte as channelWriteByte import io.ktor.utils.io.writeInt as channelWriteInt import io.ktor.utils.io.writeLong as channelWriteLong -import io.ktor.utils.io.writeByte as channelWriteByte public class ServerWriteChannel(private val delegate: ByteWriteChannel) : ByteWriteChannel by delegate { private suspend fun write(request: ByteArray, length: Int? = null) { @@ -77,7 +77,7 @@ public class ServerWriteChannel(private val delegate: ByteWriteChannel) : ByteWr gid: Int, atime: Int, mtime: Int, - ctime: Int + ctime: Int, ) { respond(Const.Message.LSTAT_V2) writeIntLittleEndian(error) @@ -132,7 +132,7 @@ public class ServerWriteChannel(private val delegate: ByteWriteChannel) : ByteWr gid: Int, atime: Int, mtime: Int, - ctime: Int + ctime: Int, ) { respond(Const.Message.DENT_V2) writeIntLittleEndian(error) diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/StubSocket.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/StubSocket.kt index 0ca878092..855937092 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/StubSocket.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/StubSocket.kt @@ -32,7 +32,7 @@ import io.ktor.utils.io.writeByte as channelWriteByte public class StubSocket( public val readChannel: ByteReadChannel = ByteChannel(false), - public val writeChannel: ByteWriteChannel = ByteChannel(false) + public val writeChannel: ByteWriteChannel = ByteChannel(false), ) : Socket { override val isClosedForWrite: Boolean get() = writeChannel.isClosedForWrite diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/DeviceExpectation.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/DeviceExpectation.kt index 095c948cc..505d2b4d0 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/DeviceExpectation.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/DeviceExpectation.kt @@ -18,7 +18,7 @@ package com.malinskiy.adam.server.stub.dsl public data class DeviceExpectation( public val serialNo: String, - private val list: MutableList Unit> = mutableListOf() + private val list: MutableList Unit> = mutableListOf(), ) { public fun session(block: suspend Session.() -> Unit) { list.add(block) diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Expectation.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Expectation.kt index 2b8da5f7c..3cbb709e7 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Expectation.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Expectation.kt @@ -35,11 +35,13 @@ public class Expectation { val transportCmd = session.input.receiveCommand() return if (transportCmd.startsWith("host:transport:")) { val serial = transportCmd.substringAfter("host:transport:") - handlers[serial]?.let { it.handle(session); true } ?: false + handlers[serial]?.let { + it.handle(session) + true + } ?: false } else { otherHandlers[transportCmd]?.invoke(session) ?: return false return true } } } - diff --git a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Session.kt b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Session.kt index a55c2e56a..10ec478d6 100644 --- a/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Session.kt +++ b/server/server-stub/src/main/kotlin/com/malinskiy/adam/server/stub/dsl/Session.kt @@ -23,7 +23,6 @@ import com.malinskiy.adam.server.stub.ServerReadChannel import com.malinskiy.adam.server.stub.ServerWriteChannel import java.io.File - public class Session(public val input: ServerReadChannel, public val output: ServerWriteChannel) { public suspend fun expectCmd(expected: () -> String): OkayFailSubSession { val transportCmd = input.receiveCommand() @@ -55,7 +54,7 @@ public class Session(public val input: ServerReadChannel, public val output: Ser when (success) { true -> Const.Message.OKAY false -> Const.Message.FAIL - } + }, ) if (!success && message != null) { @@ -73,7 +72,7 @@ public class Session(public val input: ServerReadChannel, public val output: Ser } public suspend fun respondScreencaptureV2(replay: File) { - //Extended version + // Extended version output.writeIntLittleEndian(1) val sample = replay.readBytes() @@ -83,7 +82,7 @@ public class Session(public val input: ServerReadChannel, public val output: Ser } public suspend fun respondScreencaptureV3(replay: File) { - //Extended version + // Extended version output.writeIntLittleEndian(2) val sample = replay.readBytes() @@ -121,7 +120,7 @@ public class Session(public val input: ServerReadChannel, public val output: Ser when (success) { true -> Const.Message.OKAY false -> Const.Message.FAIL - } + }, ) if (success && port != null) { @@ -182,7 +181,7 @@ public class Session(public val input: ServerReadChannel, public val output: Ser gid: Int, atime: Int, mtime: Int, - ctime: Int + ctime: Int, ) { output.respondStatV2(mode, size, error, dev, ino, nlink, uid, gid, atime, mtime, ctime) } @@ -251,7 +250,7 @@ public class Session(public val input: ServerReadChannel, public val output: Ser gid: Int, atime: Int, mtime: Int, - ctime: Int + ctime: Int, ): DoneFailSubSession { output.respondListV2(name, mode, size, error, dev, ino, nlink, uid, gid, atime, mtime, ctime) return DoneFailSubSession(this) @@ -279,7 +278,6 @@ public class Session(public val input: ServerReadChannel, public val output: Ser output.respondStringV1(response) } - public suspend fun respondConnectDevice(response: String) { output.respondStringV1(response) } diff --git a/transport-ktor/src/test/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketRegressionTest.kt b/transport-ktor/src/test/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketRegressionTest.kt index b6b522a4f..f579b0041 100644 --- a/transport-ktor/src/test/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketRegressionTest.kt +++ b/transport-ktor/src/test/kotlin/com/malinskiy/adam/transport/ktor/KtorSocketRegressionTest.kt @@ -24,9 +24,9 @@ import io.ktor.network.sockets.openReadChannel import io.ktor.network.sockets.openWriteChannel import io.ktor.utils.io.readFully import io.ktor.utils.io.writeFully -import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withTimeout import org.junit.Test From 05bb14991b198d37a811612be892ea10159799c1 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 04:40:38 +0000 Subject: [PATCH 24/50] chore: apply spotless --- .../malinskiy/adam/integration/PullE2ETest.kt | 115 ++++++++++++------ .../malinskiy/adam/integration/PushE2ETest.kt | 94 +++++++++----- .../adam/request/ValidationResponse.kt | 15 ++- .../adam/request/framebuffer/Color.kt | 8 +- .../request/logcat/ChanneledLogcatRequest.kt | 76 ++++++------ ...ProtoInstrumentationResponseTransformer.kt | 62 ++++++++-- .../vertx/VariableSizeRecordParser.kt | 31 +++-- .../InstrumentationResponseTransformerTest.kt | 43 +++++-- 8 files changed, 302 insertions(+), 142 deletions(-) diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PullE2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PullE2ETest.kt index bf45ecd75..cbeff730a 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PullE2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PullE2ETest.kt @@ -55,36 +55,50 @@ class PullE2ETest { } } - @Test fun testPull() { runBlocking { adbRule.adb.execute(ShellCommandRequest("mkdir -p /data/local/tmp/testdir/X"), adbRule.deviceSerial) adbRule.adb.execute(ShellCommandRequest("mkdir -p /data/local/tmp/testdir/Y/Z"), adbRule.deviceSerial) - adbRule.adb.execute(ShellCommandRequest("echo Xcafebabe > /data/local/tmp/testdir/X/testfilex"), adbRule.deviceSerial) - adbRule.adb.execute(ShellCommandRequest("echo Ycafebabe > /data/local/tmp/testdir/Y/testfiley"), adbRule.deviceSerial) - adbRule.adb.execute(ShellCommandRequest("echo Zcafebabe > /data/local/tmp/testdir/Y/Z/testfilez"), adbRule.deviceSerial) - //Testing non-latin filenames - adbRule.adb.execute(ShellCommandRequest("echo кафебаба > /data/local/tmp/testdir/тестовыйфайл"), adbRule.deviceSerial) + adbRule.adb.execute( + ShellCommandRequest("echo Xcafebabe > /data/local/tmp/testdir/X/testfilex"), + adbRule.deviceSerial, + ) + adbRule.adb.execute( + ShellCommandRequest("echo Ycafebabe > /data/local/tmp/testdir/Y/testfiley"), + adbRule.deviceSerial, + ) + adbRule.adb.execute( + ShellCommandRequest("echo Zcafebabe > /data/local/tmp/testdir/Y/Z/testfilez"), + adbRule.deviceSerial, + ) + // Testing non-latin filenames + adbRule.adb.execute( + ShellCommandRequest("echo кафебаба > /data/local/tmp/testdir/тестовыйфайл"), + adbRule.deviceSerial, + ) val dst = temp.newFolder() val execute = - adbRule.adb.execute(PullRequest("/data/local/tmp/testdir", dst, adbRule.supportedFeatures), adbRule.deviceSerial) + adbRule.adb.execute( + PullRequest("/data/local/tmp/testdir", dst, adbRule.supportedFeatures), + adbRule.deviceSerial, + ) - //Should create a subdir since dst already exists + // Should create a subdir since dst already exists val testdir = File(dst, "testdir") - val X = File(testdir, "X") - val Y = File(testdir, "Y") - val Z = File(Y, "Z") - val x = File(X, "testfilex") - val y = File(Y, "testfiley") - val z = File(Z, "testfilez") + val xDir = File(testdir, "X") + val yDir = File(testdir, "Y") + val zDir = File(yDir, "Z") + val x = File(xDir, "testfilex") + val y = File(yDir, "testfiley") + val z = File(zDir, "testfilez") val q = File(testdir, "тестовыйфайл") - assertThat(X).isDirectory() - assertThat(Y).isDirectory() - assertThat(Z).isDirectory() + assertThat(xDir).isDirectory() + assertThat(yDir).isDirectory() + assertThat(zDir).isDirectory() assertThat(x).isFile() assertThat(y).isFile() @@ -102,28 +116,43 @@ class PullE2ETest { runBlocking { adbRule.adb.execute(ShellCommandRequest("mkdir -p /data/local/tmp/testdir/X"), adbRule.deviceSerial) adbRule.adb.execute(ShellCommandRequest("mkdir -p /data/local/tmp/testdir/Y/Z"), adbRule.deviceSerial) - adbRule.adb.execute(ShellCommandRequest("echo Xcafebabe > /data/local/tmp/testdir/X/testfilex"), adbRule.deviceSerial) - adbRule.adb.execute(ShellCommandRequest("echo Ycafebabe > /data/local/tmp/testdir/Y/testfiley"), adbRule.deviceSerial) - adbRule.adb.execute(ShellCommandRequest("echo Zcafebabe > /data/local/tmp/testdir/Y/Z/testfilez"), adbRule.deviceSerial) - //Testing non-latin filenames - adbRule.adb.execute(ShellCommandRequest("echo кафебаба > /data/local/tmp/testdir/тестовыйфайл"), adbRule.deviceSerial) + adbRule.adb.execute( + ShellCommandRequest("echo Xcafebabe > /data/local/tmp/testdir/X/testfilex"), + adbRule.deviceSerial, + ) + adbRule.adb.execute( + ShellCommandRequest("echo Ycafebabe > /data/local/tmp/testdir/Y/testfiley"), + adbRule.deviceSerial, + ) + adbRule.adb.execute( + ShellCommandRequest("echo Zcafebabe > /data/local/tmp/testdir/Y/Z/testfilez"), + adbRule.deviceSerial, + ) + // Testing non-latin filenames + adbRule.adb.execute( + ShellCommandRequest("echo кафебаба > /data/local/tmp/testdir/тестовыйфайл"), + adbRule.deviceSerial, + ) val dst = temp.newFolder() dst.delete() val execute = - adbRule.adb.execute(PullRequest("/data/local/tmp/testdir", dst, adbRule.supportedFeatures), adbRule.deviceSerial) - - val X = File(dst, "X") - val Y = File(dst, "Y") - val Z = File(Y, "Z") - val x = File(X, "testfilex") - val y = File(Y, "testfiley") - val z = File(Z, "testfilez") + adbRule.adb.execute( + PullRequest("/data/local/tmp/testdir", dst, adbRule.supportedFeatures), + adbRule.deviceSerial, + ) + + val xDir = File(dst, "X") + val yDir = File(dst, "Y") + val zDir = File(yDir, "Z") + val x = File(xDir, "testfilex") + val y = File(yDir, "testfiley") + val z = File(zDir, "testfilez") val q = File(dst, "тестовыйфайл") - assertThat(X).isDirectory() - assertThat(Y).isDirectory() - assertThat(Z).isDirectory() + assertThat(xDir).isDirectory() + assertThat(yDir).isDirectory() + assertThat(zDir).isDirectory() assertThat(x).isFile() assertThat(y).isFile() @@ -140,13 +169,16 @@ class PullE2ETest { fun testPullFileIntoADestinationFolder() { runBlocking { adbRule.adb.execute(ShellCommandRequest("mkdir -p /data/local/tmp/testdir/X"), adbRule.deviceSerial) - adbRule.adb.execute(ShellCommandRequest("echo Xcafebabe > /data/local/tmp/testdir/X/testfilex"), adbRule.deviceSerial) + adbRule.adb.execute( + ShellCommandRequest("echo Xcafebabe > /data/local/tmp/testdir/X/testfilex"), + adbRule.deviceSerial, + ) val dst = temp.newFolder() val execute = adbRule.adb.execute( PullRequest("/data/local/tmp/testdir/X/testfilex", dst, adbRule.supportedFeatures), - adbRule.deviceSerial + adbRule.deviceSerial, ) val x = File(dst, "testfilex") @@ -162,18 +194,21 @@ class PullE2ETest { runBlocking { adbRule.adb.execute(ShellCommandRequest("mkdir -p /data/local/tmp/testdir/X"), adbRule.deviceSerial) adbRule.adb.execute(ShellCommandRequest("touch /data/local/tmp/testdir/X/testfilex"), adbRule.deviceSerial) - adbRule.adb.execute(ShellCommandRequest("echo Xcafebabe > /data/local/tmp/testdir/X/testfiley"), adbRule.deviceSerial) + adbRule.adb.execute( + ShellCommandRequest("echo Xcafebabe > /data/local/tmp/testdir/X/testfiley"), + adbRule.deviceSerial, + ) val dst = temp.newFolder() val execute = adbRule.adb.execute( PullRequest("/data/local/tmp/testdir/X", dst, adbRule.supportedFeatures), - adbRule.deviceSerial + adbRule.deviceSerial, ) - val X = File(dst, "X") - val x = File(X, "testfilex") - val y = File(X, "testfiley") + val xDir = File(dst, "X") + val x = File(xDir, "testfilex") + val y = File(xDir, "testfiley") assertThat(x).isFile() assertThat(y).isFile() diff --git a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PushE2ETest.kt b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PushE2ETest.kt index 566efa294..28723cab3 100644 --- a/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PushE2ETest.kt +++ b/adam/src/integrationTest/kotlin/com/malinskiy/adam/integration/PushE2ETest.kt @@ -60,20 +60,35 @@ class PushE2ETest { @Test fun testPush() { val source = temp.newFolder() - val X = File(source, "X").apply { mkdir() } - val Y = File(source, "Y").apply { mkdir() } - val Z = File(Y, "Z").apply { mkdir() } - val x = File(X, "testfilex").apply { createNewFile(); writeText("Xcafebabe\n") } - val y = File(Y, "testfiley").apply { createNewFile(); writeText("Ycafebabe\n") } - val z = File(Z, "testfilez").apply { createNewFile(); writeText("Zcafebabe\n") } - //Testing non-latin filenames - val q = File(source, "тестовыйфайл").apply { createNewFile(); writeText("кафебаба\n") } + val xDir = File(source, "X").apply { mkdir() } + val yDir = File(source, "Y").apply { mkdir() } + val zDir = File(yDir, "Z").apply { mkdir() } + val x = File(xDir, "testfilex").apply { + createNewFile() + writeText("Xcafebabe\n") + } + val y = File(yDir, "testfiley").apply { + createNewFile() + writeText("Ycafebabe\n") + } + val z = File(zDir, "testfilez").apply { + createNewFile() + writeText("Zcafebabe\n") + } + // Testing non-latin filenames + val q = File(source, "тестовыйфайл").apply { + createNewFile() + writeText("кафебаба\n") + } runBlocking { val execute = - adbRule.adb.execute(PushRequest(source, "/data/local/tmp/testdir", adbRule.supportedFeatures), adbRule.deviceSerial) + adbRule.adb.execute( + PushRequest(source, "/data/local/tmp/testdir", adbRule.supportedFeatures), + adbRule.deviceSerial, + ) - //Should create a subdir since dst already exists + // Should create a subdir since dst already exists assertThat(statFile("/data/local/tmp/testdir").isDirectory()).isTrue() assertThat(statFile("/data/local/tmp/testdir/X").isDirectory()).isTrue() @@ -94,13 +109,19 @@ class PushE2ETest { @Test fun testPushCreatingSubdir() { val source = temp.newFolder("testdir with special 'chars()") - val x = File(source, "testfilex").apply { createNewFile(); writeText("Xcafebabe\n") } + val x = File(source, "testfilex").apply { + createNewFile() + writeText("Xcafebabe\n") + } runBlocking { val execute = - adbRule.adb.execute(PushRequest(source, "/data/local/tmp", adbRule.supportedFeatures), adbRule.deviceSerial) + adbRule.adb.execute( + PushRequest(source, "/data/local/tmp", adbRule.supportedFeatures), + adbRule.deviceSerial, + ) - //Should create a subdir since dst already exists + // Should create a subdir since dst already exists assertThat(statFile("/data/local/tmp/testdir with special 'chars()").isDirectory()).isTrue() assertThat(statFile("/data/local/tmp/testdir with special 'chars()/testfilex").isRegularFile()).isTrue() } @@ -116,28 +137,43 @@ class PushE2ETest { runBlocking { adbRule.adb.execute(ShellCommandRequest("mkdir -p /data/local/tmp/testdir/X"), adbRule.deviceSerial) adbRule.adb.execute(ShellCommandRequest("mkdir -p /data/local/tmp/testdir/Y/Z"), adbRule.deviceSerial) - adbRule.adb.execute(ShellCommandRequest("echo Xcafebabe > /data/local/tmp/testdir/X/testfilex"), adbRule.deviceSerial) - adbRule.adb.execute(ShellCommandRequest("echo Ycafebabe > /data/local/tmp/testdir/Y/testfiley"), adbRule.deviceSerial) - adbRule.adb.execute(ShellCommandRequest("echo Zcafebabe > /data/local/tmp/testdir/Y/Z/testfilez"), adbRule.deviceSerial) - //Testing non-latin filenames - adbRule.adb.execute(ShellCommandRequest("echo кафебаба > /data/local/tmp/testdir/тестовыйфайл"), adbRule.deviceSerial) + adbRule.adb.execute( + ShellCommandRequest("echo Xcafebabe > /data/local/tmp/testdir/X/testfilex"), + adbRule.deviceSerial, + ) + adbRule.adb.execute( + ShellCommandRequest("echo Ycafebabe > /data/local/tmp/testdir/Y/testfiley"), + adbRule.deviceSerial, + ) + adbRule.adb.execute( + ShellCommandRequest("echo Zcafebabe > /data/local/tmp/testdir/Y/Z/testfilez"), + adbRule.deviceSerial, + ) + // Testing non-latin filenames + adbRule.adb.execute( + ShellCommandRequest("echo кафебаба > /data/local/tmp/testdir/тестовыйфайл"), + adbRule.deviceSerial, + ) val dst = temp.newFolder() dst.delete() val execute = - adbRule.adb.execute(PullRequest("/data/local/tmp/testdir", dst, adbRule.supportedFeatures), adbRule.deviceSerial) - - val X = File(dst, "X") - val Y = File(dst, "Y") - val Z = File(Y, "Z") - val x = File(X, "testfilex") - val y = File(Y, "testfiley") - val z = File(Z, "testfilez") + adbRule.adb.execute( + PullRequest("/data/local/tmp/testdir", dst, adbRule.supportedFeatures), + adbRule.deviceSerial, + ) + + val xDir = File(dst, "X") + val yDir = File(dst, "Y") + val zDir = File(yDir, "Z") + val x = File(xDir, "testfilex") + val y = File(yDir, "testfiley") + val z = File(zDir, "testfilez") val q = File(dst, "тестовыйфайл") - assertThat(X).isDirectory() - assertThat(Y).isDirectory() - assertThat(Z).isDirectory() + assertThat(xDir).isDirectory() + assertThat(yDir).isDirectory() + assertThat(zDir).isDirectory() assertThat(x).isFile() assertThat(y).isFile() diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/ValidationResponse.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/ValidationResponse.kt index 8f8b74638..69e9d99ed 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/ValidationResponse.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/ValidationResponse.kt @@ -22,19 +22,26 @@ import java.util.* public data class ValidationResponse( public val success: Boolean, - public val message: String? + public val message: String?, ) { public companion object { public val Success: ValidationResponse = ValidationResponse(true, null) public fun missingFeature(feature: Feature): String = "${feature.name} is not supported by device" - public fun missingEitherFeature(vararg feature: Feature): String = "Supported features must include either of ${feature.joinToString()}" - public fun oneOfFilesShouldBe(extension: String): String = "At least one of the files has to be an ${extension.uppercase(Locale.ENGLISH)} file" + public fun missingEitherFeature(vararg feature: Feature): String { + return "Supported features must include either of ${feature.joinToString()}" + } + + public fun oneOfFilesShouldBe(extension: String): String { + return "At least one of the files has to be an ${extension.uppercase(Locale.ENGLISH)} file" + } public fun packageShouldExist(file: File): String = "Package ${file.absolutePath} doesn't exist" public fun packageShouldBeRegularFile(file: File): String = "Package ${file.absolutePath} is not a regular file" public fun packageShouldBeSupportedExtension(file: File, supported: Set): String = "Unsupported package extension ${file.extension}. Should be on of ${supported.joinToString()}}" - public fun pathShouldNotBeLong(): String = "Remote path should be less that ${Const.MAX_REMOTE_PATH_LENGTH} bytes" + public fun pathShouldNotBeLong(): String { + return "Remote path should be less that ${Const.MAX_REMOTE_PATH_LENGTH} bytes" + } } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/Color.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/Color.kt index 04eaaecd5..7f1dc8eec 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/Color.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/Color.kt @@ -14,6 +14,8 @@ * limitations under the License. */ +@file:Suppress("ktlint:standard:class-naming", "ktlint:standard:function-naming") + package com.malinskiy.adam.request.framebuffer import kotlin.math.roundToInt @@ -43,7 +45,7 @@ public object Color { blueOffset: Int, blueLength: Int, alphaOffset: Int, - alphaLength: Int + alphaLength: Int, ): Int { val r = value.ushr(redOffset) and getMask(redLength) shl 8 - redLength val g = value.ushr(greenOffset) and getMask(greenLength) shl 8 - greenLength @@ -62,7 +64,7 @@ public object Color { blueOffset: Int, blueLength: Int, alphaOffset: Int, - alphaLength: Int + alphaLength: Int, ): ByteArray { val r = (value.ushr(redOffset) and getMask(redLength)) xshl (8 - redLength) val g = (value.ushr(greenOffset) and getMask(greenLength)) xshl (8 - greenLength) @@ -76,7 +78,7 @@ public object Color { return byteArrayOf( (r * alphaMultiplier).roundToInt().toByte(), (g * alphaMultiplier).roundToInt().toByte(), - (b * alphaMultiplier).roundToInt().toByte() + (b * alphaMultiplier).roundToInt().toByte(), ) } } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/ChanneledLogcatRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/ChanneledLogcatRequest.kt index f375bc475..3698f9818 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/ChanneledLogcatRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/logcat/ChanneledLogcatRequest.kt @@ -24,25 +24,28 @@ public class ChanneledLogcatRequest( buffers: List = emptyList(), pid: Long? = null, lastReboot: Boolean? = null, - filters: List = emptyList() + filters: List = emptyList(), ) : ChanneledShellCommandRequest( cmd = "logcat" + - (since?.let { + ( + since?.let { " -T ${since.text}" - } ?: "") + - " ${modes.joinToString(separator = " ") { "-v $it" }}" + - if (buffers.isNotEmpty()) { - " ${buffers.joinToString(separator = " ") { "-b $it" }}" - } else { - "" - } + - "${pid?.let { " --pid=$it" } ?: ""}" + - "${lastReboot?.let { " -L" } ?: ""}" + - " ${filters.joinToString(separator = " ") { "${it.tag}:${it.level.name}" }}" - .trimEnd(), + } ?: "" + ) + + " ${modes.joinToString(separator = " ") { "-v $it" }}" + + if (buffers.isNotEmpty()) { + " ${buffers.joinToString(separator = " ") { "-b $it" }}" + } else { + "" + } + + "${pid?.let { " --pid=$it" } ?: ""}" + + "${lastReboot?.let { " -L" } ?: ""}" + + " ${filters.joinToString(separator = " ") { "${it.tag}:${it.level.name}" }}" + .trimEnd(), socketIdleTimeout = Long.MAX_VALUE, ) +@Suppress("ktlint:standard:enum-entry-name-case") public enum class LogcatReadMode { brief, long, @@ -53,58 +56,59 @@ public enum class LogcatReadMode { threadtime, time, - //Show log buffer event descriptions. This modifier affects event log buffer messages only, and has no effect on the other non-binary buffers. The event descriptions come from the event-log-tags database. + // Show log buffer event descriptions. This modifier affects event log buffer messages only, and has no effect on the other non-binary buffers. The event descriptions come from the event-log-tags database. descriptive, - //Show each priority level with a different color + // Show each priority level with a different color color, - //Display time in seconds starting from Jan 1, 1970 + // Display time in seconds starting from Jan 1, 1970 epoch, - //Display time in CPU seconds starting from the last boot + // Display time in CPU seconds starting from the last boot monotonic, - //Ensure that any binary logging content is escaped + // Ensure that any binary logging content is escaped printable, - //If permitted by access controls, display the UID or Android ID of the logged process + // If permitted by access controls, display the UID or Android ID of the logged process uid, - //Display the time with precision down to microseconds + // Display the time with precision down to microseconds usec, - //Display time as UTC + // Display time as UTC UTC, - //Add the year to the displayed time + // Add the year to the displayed time year, - //Add the local time zone to the displayed time - zone + // Add the local time zone to the displayed time + zone, } +@Suppress("ktlint:standard:enum-entry-name-case") public enum class LogcatBuffer { - //View the buffer that contains radio/telephony related messages + // View the buffer that contains radio/telephony related messages radio, - //View the interpreted binary system event buffer messages + // View the interpreted binary system event buffer messages events, - //View the main log buffer (default) does not contain system and crash log messages + // View the main log buffer (default) does not contain system and crash log messages main, - //View the system log buffer (default) + // View the system log buffer (default) system, - //View the crash log buffer (default) + // View the crash log buffer (default) crash, - //View all buffers + // View all buffers all, - //Reports main, system, and crash buffers - default + // Reports main, system, and crash buffers + default, } public enum class LogcatVerbosityLevel { @@ -114,9 +118,13 @@ public enum class LogcatVerbosityLevel { W, E, F, - S + S, } public data class LogcatFilterSpec(public val tag: String, public val level: LogcatVerbosityLevel) -public val SupressAll: LogcatFilterSpec = LogcatFilterSpec("*", LogcatVerbosityLevel.S) +public val suppressAll: LogcatFilterSpec = LogcatFilterSpec("*", LogcatVerbosityLevel.S) + +@Deprecated("Use suppressAll", ReplaceWith("suppressAll")) +@Suppress("ktlint:standard:property-naming") +public val SupressAll: LogcatFilterSpec = suppressAll diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/ProtoInstrumentationResponseTransformer.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/ProtoInstrumentationResponseTransformer.kt index 4f6372ac6..f0ba28bdf 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/ProtoInstrumentationResponseTransformer.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/ProtoInstrumentationResponseTransformer.kt @@ -19,9 +19,23 @@ package com.malinskiy.adam.request.transform import com.android.commands.am.InstrumentationData import com.google.protobuf.InvalidProtocolBufferException import com.malinskiy.adam.Const -import com.malinskiy.adam.extension.* -import com.malinskiy.adam.request.testrunner.* -import com.malinskiy.adam.request.testrunner.model.* +import com.malinskiy.adam.extension.compatLimit +import com.malinskiy.adam.extension.compatPosition +import com.malinskiy.adam.request.testrunner.ProgressiveResponseTransformer +import com.malinskiy.adam.request.testrunner.SessionResultCode +import com.malinskiy.adam.request.testrunner.StatusKey +import com.malinskiy.adam.request.testrunner.model.Status +import com.malinskiy.adam.request.testrunner.model.TestAssumptionFailed +import com.malinskiy.adam.request.testrunner.model.TestEnded +import com.malinskiy.adam.request.testrunner.model.TestEvent +import com.malinskiy.adam.request.testrunner.model.TestFailed +import com.malinskiy.adam.request.testrunner.model.TestIdentifier +import com.malinskiy.adam.request.testrunner.model.TestIgnored +import com.malinskiy.adam.request.testrunner.model.TestRunEnded +import com.malinskiy.adam.request.testrunner.model.TestRunFailed +import com.malinskiy.adam.request.testrunner.model.TestRunStartedEvent +import com.malinskiy.adam.request.testrunner.model.TestStarted +import com.malinskiy.adam.request.testrunner.model.TestStatusAggregator import java.io.File import java.io.RandomAccessFile import java.nio.MappedByteBuffer @@ -67,7 +81,10 @@ public class ProtoInstrumentationResponseTransformer(maxProtobufPacketLength: Lo for (status in session.testStatusList ?: emptyList()) { if (state == NotStarted) { val testCount = - status.results?.entriesList?.filter { entry -> entry.key?.let { it == StatusKey.NUMTESTS.value } ?: false } + status.results?.entriesList?.filter { entry -> + entry.key?.let { it == StatusKey.NUMTESTS.value } + ?: false + } ?.mapNotNull { it.valueInt } ?.firstOrNull() ?: 0 @@ -86,10 +103,21 @@ public class ProtoInstrumentationResponseTransformer(maxProtobufPacketLength: Lo if (entry.key != null) { when (StatusKey.of(entry.key)) { StatusKey.TEST -> testMethodName = entry.valueString ?: testClassName + StatusKey.CLASS -> testClassName = entry.valueString ?: testMethodName + StatusKey.STACK -> stackTrace = entry.valueString ?: stackTrace - StatusKey.CURRENT -> Unit //Test index - StatusKey.NUMTESTS, StatusKey.ERROR, StatusKey.SHORTMSG, StatusKey.STREAM, StatusKey.ID -> Unit + + StatusKey.CURRENT -> Unit + + // Test index + StatusKey.NUMTESTS, + StatusKey.ERROR, + StatusKey.SHORTMSG, + StatusKey.STREAM, + StatusKey.ID, + -> Unit + StatusKey.UNKNOWN -> testMetrics[entry.key] = entry.valueToString() } } @@ -101,7 +129,10 @@ public class ProtoInstrumentationResponseTransformer(maxProtobufPacketLength: Lo testClassName = previousTestStatus.key.className testMethodName = previousTestStatus.key.testName resultCodeOverride = previousTestStatus.value.statusCode - } ?: run { testClassName = ""; testMethodName = "" } + } ?: run { + testClassName = "" + testMethodName = "" + } } if (testClassName.isNotBlank() && testMethodName.isNotBlank()) { @@ -112,8 +143,8 @@ public class ProtoInstrumentationResponseTransformer(maxProtobufPacketLength: Lo resultCodeOverride ?: Status.valueOf(status.resultCode), status.logcat, stackTrace, - testMetrics - ) + testMetrics, + ), ) } } @@ -139,6 +170,7 @@ public class ProtoInstrumentationResponseTransformer(maxProtobufPacketLength: Lo } } } + InstrumentationData.SessionStatusCode.SESSION_ABORTED -> { val errorText = session.sessionStatus.errorText ?: "" val lastTest = testStatuses.entries.lastOrNull() @@ -152,6 +184,7 @@ public class ProtoInstrumentationResponseTransformer(maxProtobufPacketLength: Lo events.add(TestRunFailed(errorText)) } + else -> Unit } @@ -162,7 +195,9 @@ public class ProtoInstrumentationResponseTransformer(maxProtobufPacketLength: Lo if (sessionOutput != null) { val matchResult = timeRegex.find(sessionOutput) - val elapsedTime = matchResult?.groups?.get(1)?.let { it.value.toFloatOrNull() }?.let { (it * 1000).toLong() } ?: 0L + val elapsedTime = + matchResult?.groups?.get(1)?.let { it.value.toFloatOrNull() }?.let { (it * 1000).toLong() } + ?: 0L events.add(TestRunEnded(elapsedTime, testRunMetrics)) } } @@ -179,7 +214,7 @@ public class ProtoInstrumentationResponseTransformer(maxProtobufPacketLength: Lo return events } catch (e: InvalidProtocolBufferException) { - //wait for more input + // wait for more input buffer.compatPosition(buffer.limit()) return null } @@ -197,7 +232,7 @@ public class ProtoInstrumentationResponseTransformer(maxProtobufPacketLength: Lo resultCode: Status, logcat: String?, stackTrace: String, - testMetrics: Map + testMetrics: Map, ): List { val id = TestIdentifier(className, methodName) var events = mutableListOf() @@ -217,13 +252,16 @@ public class ProtoInstrumentationResponseTransformer(maxProtobufPacketLength: Lo Status.ERROR, Status.FAILURE -> { events.add(TestFailed(id, stackTrace)) } + Status.IGNORED -> { events.add(TestIgnored(id)) statusAggregator.logcatBuilder.clear() } + Status.ASSUMPTION_FAILURE -> { events.add(TestAssumptionFailed(id, stackTrace)) } + Status.SUCCESS, Status.START, Status.IN_PROGRESS, Status.UNKNOWN -> Unit } diff --git a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VariableSizeRecordParser.kt b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VariableSizeRecordParser.kt index d9f2985e1..d80f19f00 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VariableSizeRecordParser.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/transport/vertx/VariableSizeRecordParser.kt @@ -22,11 +22,11 @@ import io.vertx.core.streams.ReadStream import kotlin.math.min public class VariableSizeRecordParser( - private val stream: ReadStream? = null + private val stream: ReadStream? = null, ) : Handler, ReadStream { // Empty and unmodifiable - private val EMPTY_BUFFER: Buffer = Buffer.buffer() - private var buff: Buffer = EMPTY_BUFFER + private val emptyBuffer: Buffer = Buffer.buffer() + private var buff: Buffer = emptyBuffer private val bufferLock = Any() private var pos = 0 // Current position in buffer private var start = 0 // Position of beginning of current record @@ -101,7 +101,7 @@ public class VariableSizeRecordParser( } while (true) val length = buff.length() if (start == length) { - buff = EMPTY_BUFFER + buff = emptyBuffer } else if (start > 0) { buff = buff.getBuffer(start, length) } @@ -133,19 +133,26 @@ public class VariableSizeRecordParser( endHandler?.handle(null) } - override fun exceptionHandler(handler: Handler?): VariableSizeRecordParser = apply { exceptionHandler = handler } + override fun exceptionHandler(handler: Handler?): VariableSizeRecordParser = apply { + exceptionHandler = + handler + } override fun handler(handler: Handler?): ReadStream { eventHandler = handler if (stream != null) { if (handler != null) { - stream.endHandler(Handler { - streamEnded = true - handleParsing() - }) - stream.exceptionHandler(Handler { err: Throwable -> - exceptionHandler?.handle(err) - }) + stream.endHandler( + Handler { + streamEnded = true + handleParsing() + }, + ) + stream.exceptionHandler( + Handler { err: Throwable -> + exceptionHandler?.handle(err) + }, + ) stream.handler(this) } else { stream.handler(null) diff --git a/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformerTest.kt b/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformerTest.kt index 61c958b75..1cd651b1b 100644 --- a/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformerTest.kt +++ b/adam/src/test/kotlin/com/malinskiy/adam/request/testrunner/transform/InstrumentationResponseTransformerTest.kt @@ -45,7 +45,9 @@ class InstrumentationResponseTransformerTest { transformer.transform()?.let { events.addAll(it) } assertThat(events.map { it.toString() }.reduce { acc, s -> acc + "\n" + s }) - .isEqualTo(javaClass.getResourceAsStream("/instrumentation/log_3.expected").reader().readText().trimEnd()) + .isEqualTo( + javaClass.getResourceAsStream("/instrumentation/log_3.expected").reader().readText().trimEnd(), + ) } } @@ -66,7 +68,9 @@ class InstrumentationResponseTransformerTest { transformer.transform()?.let { events.addAll(it) } assertThat(events.map { it.toString() }.reduce { acc, s -> acc + "\n" + s }) - .isEqualTo(javaClass.getResourceAsStream("/instrumentation/log_2.expected").reader().readText().trimEnd()) + .isEqualTo( + javaClass.getResourceAsStream("/instrumentation/log_2.expected").reader().readText().trimEnd(), + ) } } @@ -87,7 +91,9 @@ class InstrumentationResponseTransformerTest { transformer.transform()?.let { events.addAll(it) } assertThat(events.map { it.toString() }.reduce { acc, s -> acc + "\n" + s }) - .isEqualTo(javaClass.getResourceAsStream("/instrumentation/log_1.expected").reader().readText().trimEnd()) + .isEqualTo( + javaClass.getResourceAsStream("/instrumentation/log_1.expected").reader().readText().trimEnd(), + ) } } @@ -117,7 +123,9 @@ class InstrumentationResponseTransformerTest { transformer.transform()?.let { events.addAll(it) } assertThat(events.map { it.toString() }.reduce { acc, s -> acc + "\n" + s }) - .isEqualTo(javaClass.getResourceAsStream("/instrumentation/log_4.expected").reader().readText().trimEnd()) + .isEqualTo( + javaClass.getResourceAsStream("/instrumentation/log_4.expected").reader().readText().trimEnd(), + ) } } @@ -138,7 +146,9 @@ class InstrumentationResponseTransformerTest { transformer.transform()?.let { events.addAll(it) } assertThat(events.map { it.toString() }.reduce { acc, s -> acc + "\n" + s }) - .isEqualTo(javaClass.getResourceAsStream("/instrumentation/log_5.expected").reader().readText().trimEnd()) + .isEqualTo( + javaClass.getResourceAsStream("/instrumentation/log_5.expected").reader().readText().trimEnd(), + ) } } @@ -160,8 +170,15 @@ class InstrumentationResponseTransformerTest { } transformer.transform()?.let { events.addAll(it) } + val expected = javaClass + .getResourceAsStream("/instrumentation/log_6.expected") + .reader() + .readText() + .trimEnd() + .trimEnd() + assertThat(events.map { it.toString() }.reduce { acc, s -> acc + "\n" + s }) - .isEqualTo(javaClass.getResourceAsStream("/instrumentation/log_6.expected").reader().readText().trimEnd().trimEnd()) + .isEqualTo(expected) } @Test @@ -176,7 +193,10 @@ class InstrumentationResponseTransformerTest { val events = mutableListOf() for (line in lines) { val part1 = line.substring(0, 7 * line.length / 8) - val part2 = line.substring(7 * line.length / 8, line.length) + val part2 = line.substring( + 7 * line.length / 8, + line.length, + ) val bytes1 = (part1).toByteArray(Const.DEFAULT_TRANSPORT_ENCODING) val bytes2 = (part2 + '\n').toByteArray(Const.DEFAULT_TRANSPORT_ENCODING) transformer.process(bytes1, 0, bytes1.size)?.let { @@ -188,8 +208,15 @@ class InstrumentationResponseTransformerTest { } transformer.transform()?.let { events.addAll(it) } + val expected = javaClass + .getResourceAsStream("/instrumentation/log_6.expected") + .reader() + .readText() + .trimEnd() + .trimEnd() + assertThat(events.map { it.toString() }.reduce { acc, s -> acc + "\n" + s }) - .isEqualTo(javaClass.getResourceAsStream("/instrumentation/log_6.expected").reader().readText().trimEnd().trimEnd()) + .isEqualTo(expected) } /** From f7f64faf895a43f4020daaf39f3237132b531a12 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 04:43:56 +0000 Subject: [PATCH 25/50] chore(deps): remove gradle-versions plugin --- build.gradle.kts | 15 --------------- gradle/libs.versions.toml | 3 +-- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 2d02a1cbc..9c7b23ebf 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,9 +1,7 @@ -import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask import org.gradle.api.publish.PublishingExtension import java.util.Locale plugins { - alias(libs.plugins.gradle.versions) alias(libs.plugins.vanniktech.maven.publish) apply false } @@ -11,19 +9,6 @@ version = providers.environmentVariable("RELEASE_TAG") .map { it.removePrefix("v") } .getOrElse(libs.versions.adam.get()) -fun isNonStable(version: String): Boolean { - val stableKeyword = listOf("RELEASE", "FINAL", "GA").any { version.uppercase(Locale.ENGLISH).contains(it) } - val regex = "^[0-9,.v-]+(-r)?$".toRegex() - val isStable = stableKeyword || regex.matches(version) - return isStable.not() -} - -tasks.withType { - rejectVersionIf { - isNonStable(candidate.version) && !isNonStable(currentVersion) - } -} - subprojects { version = rootProject.version diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 64e1cf212..1672f15c9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,7 +22,7 @@ javax = "1.3.2" androidGradle = "9.0.0" testMonitor = "1.8.0" testRunner = "1.7.0" -gradleVersionsPlugin = "0.53.0" + vanniktechMavenPublish = "0.36.0" dokka = "2.1.0" @@ -68,5 +68,4 @@ kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } protobuf = { id = "com.google.protobuf", version.ref = "protobufGradle" } android-library = { id = "com.android.library", version.ref = "androidGradle" } -gradle-versions = { id = "com.github.ben-manes.versions", version.ref = "gradleVersionsPlugin" } vanniktech-maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "vanniktechMavenPublish" } From 0edcdc988578f7c77ccbc15fbd4707c2c9009e04 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 04:55:03 +0000 Subject: [PATCH 26/50] fix: reorganize imports in ProtoInstrumentationResponseTransformer --- ...ProtoInstrumentationResponseTransformer.kt | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/ProtoInstrumentationResponseTransformer.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/ProtoInstrumentationResponseTransformer.kt index f0ba28bdf..6f527335f 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/ProtoInstrumentationResponseTransformer.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/testrunner/transform/ProtoInstrumentationResponseTransformer.kt @@ -21,20 +21,23 @@ import com.google.protobuf.InvalidProtocolBufferException import com.malinskiy.adam.Const import com.malinskiy.adam.extension.compatLimit import com.malinskiy.adam.extension.compatPosition -import com.malinskiy.adam.request.testrunner.ProgressiveResponseTransformer -import com.malinskiy.adam.request.testrunner.SessionResultCode -import com.malinskiy.adam.request.testrunner.StatusKey +import com.malinskiy.adam.request.testrunner.TestAssumptionFailed +import com.malinskiy.adam.request.testrunner.TestEnded +import com.malinskiy.adam.request.testrunner.TestEvent +import com.malinskiy.adam.request.testrunner.TestFailed +import com.malinskiy.adam.request.testrunner.TestIdentifier +import com.malinskiy.adam.request.testrunner.TestIgnored +import com.malinskiy.adam.request.testrunner.TestRunEnded +import com.malinskiy.adam.request.testrunner.TestRunFailed +import com.malinskiy.adam.request.testrunner.TestRunStartedEvent +import com.malinskiy.adam.request.testrunner.TestStarted +import com.malinskiy.adam.request.testrunner.model.Finished +import com.malinskiy.adam.request.testrunner.model.NotStarted +import com.malinskiy.adam.request.testrunner.model.Running +import com.malinskiy.adam.request.testrunner.model.SessionResultCode +import com.malinskiy.adam.request.testrunner.model.State import com.malinskiy.adam.request.testrunner.model.Status -import com.malinskiy.adam.request.testrunner.model.TestAssumptionFailed -import com.malinskiy.adam.request.testrunner.model.TestEnded -import com.malinskiy.adam.request.testrunner.model.TestEvent -import com.malinskiy.adam.request.testrunner.model.TestFailed -import com.malinskiy.adam.request.testrunner.model.TestIdentifier -import com.malinskiy.adam.request.testrunner.model.TestIgnored -import com.malinskiy.adam.request.testrunner.model.TestRunEnded -import com.malinskiy.adam.request.testrunner.model.TestRunFailed -import com.malinskiy.adam.request.testrunner.model.TestRunStartedEvent -import com.malinskiy.adam.request.testrunner.model.TestStarted +import com.malinskiy.adam.request.testrunner.model.StatusKey import com.malinskiy.adam.request.testrunner.model.TestStatusAggregator import java.io.File import java.io.RandomAccessFile From 0ce86882a528793d439092145d3cefe6fe4148dc Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 04:57:49 +0000 Subject: [PATCH 27/50] ci: simplify publishing --- .buildsystem/deploy-github.sh | 27 ------------- .buildsystem/deploy-sonatype.sh | 27 ------------- .buildsystem/secring.gpg | Bin 4878 -> 0 bytes .github/workflows/deploy-github-release.yaml | 21 ---------- .../workflows/deploy-sonatype-release.yaml | 21 ---------- .../workflows/deploy-sonatype-snapshot.yaml | 23 ----------- .github/workflows/publish.yaml | 38 ++++++++++++++++++ 7 files changed, 38 insertions(+), 119 deletions(-) delete mode 100755 .buildsystem/deploy-github.sh delete mode 100755 .buildsystem/deploy-sonatype.sh delete mode 100644 .buildsystem/secring.gpg delete mode 100644 .github/workflows/deploy-github-release.yaml delete mode 100644 .github/workflows/deploy-sonatype-release.yaml delete mode 100644 .github/workflows/deploy-sonatype-snapshot.yaml create mode 100644 .github/workflows/publish.yaml diff --git a/.buildsystem/deploy-github.sh b/.buildsystem/deploy-github.sh deleted file mode 100755 index 2980e730e..000000000 --- a/.buildsystem/deploy-github.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash -cd $(dirname $0)/.. - -if [ -z "$GITHUB_MAVEN_USERNAME" ]; then - echo "error: please set GITHUB_MAVEN_USERNAME environment variable" - exit 1 -fi - -if [ -z "$GITHUB_TOKEN" ]; then - echo "error: please set GITHUB_MAVEN_PASSWORD environment variable" - exit 1 -fi - -if [ -z "$GPG_PASSPHRASE" ]; then - echo "error: please set GPG_PASSPHRASE environment variable" - exit 1 -fi - -if [ -n "$GIT_TAG_NAME" ]; then - echo "on a tag -> deploy release version $GIT_TAG_NAME" - ./gradlew assemble -PreleaseMode=RELEASE - ./gradlew publishDefaultPublicationToGitHubRepository -PreleaseMode=RELEASE -else - echo "not on a tag -> deploy snapshot version" - ./gradlew assemble -PreleaseMode=SNAPSHOT - ./gradlew publishDefaultPublicationToGitHubRepository -PreleaseMode=SNAPSHOT -fi diff --git a/.buildsystem/deploy-sonatype.sh b/.buildsystem/deploy-sonatype.sh deleted file mode 100755 index 73001156f..000000000 --- a/.buildsystem/deploy-sonatype.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash -cd $(dirname $0)/.. - -if [ -z "$SONATYPE_USERNAME" ]; then - echo "error: please set SONATYPE_USERNAME environment variable" - exit 1 -fi - -if [ -z "$SONATYPE_PASSWORD" ]; then - echo "error: please set SONATYPE_PASSWORD environment variable" - exit 1 -fi - -if [ -z "$GPG_PASSPHRASE" ]; then - echo "error: please set GPG_PASSPHRASE environment variable" - exit 1 -fi - -if [ -z "$GIT_TAG_NAME" ]; then - echo "not on a tag -> deploy snapshot version" - ./gradlew assemble -PreleaseMode=SNAPSHOT - ./gradlew publishDefaultPublicationToOSSHRRepository -PreleaseMode=SNAPSHOT -else - echo "on a tag -> deploy release version $GIT_TAG_NAME" - ./gradlew assemble -PreleaseMode=RELEASE - ./gradlew publishDefaultPublicationToOSSHRRepository -PreleaseMode=RELEASE -fi diff --git a/.buildsystem/secring.gpg b/.buildsystem/secring.gpg deleted file mode 100644 index 42469d32d9382b27b087df973cd78cfb3ae7af2a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4878 zcmV+p6Y=bo2R;N;Z<+T25CEl?RKJ^SDT6SV10@ARYq@9{WWI`(;TR2ehJB2TgB5>I zA+?+Dlj{Srx=h^b`u3CVp7wgBI67Kc$m%Z61#6eiFqNa$Q-4X`dg+SJ-bfs@d4mrK z{P$7?5Lml-WJ}GMF=4`^2i2leV8v!DHb!}#U_BKg#QZ__z$x%}s=}cuvtoT{S_Mql z=?hxdDlvQl@%vzn3J>HZb84xRi;Mu(dV3C`=p^TqAVxzi7X0ITx3kG%eV1-XN~(R> zO6bYjQ>xUYu)yS(Gq@u89Hh31rjYQiK23tN9u(E@9fg}O6__@ni_Ak&c5 z?CV$ICh}-bUEj*=U4?g6$)Rp4e|GsN{x|Wu7%R15gj35j`MuleYB$PmEAbLh!e5|0 z&OPcH&sQLdoGb##O;YLq-c0nAH1Z!|a2aUFcoaC?68&cs3Gj{9M1;i*yAi9`I$}n@ zDb+T;7&*%m|E=F&fL^a18O=(ot^D5a6_`LPCwa8h5_fKa*8f8Xzv^1TmCfc51dEf_M=ciE!`m6Lkv!5T?B#&LPzDWkd77 zOy%nt51`Yva;c}(JH{d$SE?7xeu`stWnl+Bt<@GgQhrD<2$*gb&Y0$@NEGI`uVrmo zvhP6hj2Yvk95Qpg{d5h*+>-fnEoajqXp$5#$UzgSB*Wd` z{A#ZBriem^81Ui>w=93fZvnlc3rGRTvY!1AC6|$9yx~5$I&;kVRgCvYvSidC`j&Yr z9k_y3x;Ja;436sz9=+R7u~d~aS%tR01o>l?Sd`x&RN{RIr36Y9FpYF#b7GBI4HHNp z{reP9WS?VCALuW+J%!%BAJpQoM|f`GnD;x!%V-fvr`w!qY9(UB=?;t>=BpKk?)V$0 z>L^i32CK|d+@I1qHuMu_`($5tWPyE&djZm=ZPhqqeg2FbADAH{)_Hbm010j)mVeK0 zo#|JIRq*D|U~_T>r55mx60|1MzV9W7HVco%)$)7|wj!SuN}8pDnx zc1Le}7%`om^7DQwFtGGOSx;e|t2zFhPm8Cj9x5XBt9Aqzb+14?NwAjtLRtis@6ex= zX#IOG{dUXOff*wc!6t^tNFhUCJUp7>k};KQ+$7@J+@r(abrkAHY{qPC&8E#!Yz+LH zr|m@TKTD!h;$Lr%D*q|xyq}P{8DA0H0GA!fI35(VL$8xPW+P{-<7$&Z znn|f-_N)2zY0~H7h7%s8?^Q6=s;*u=+lo$sCeV+9dmnk8FKalkp7 z+(S4k@~uv9t}DvQ*@N1-Sqvc$jH}pFpST-^V>^7>ufAu`E7fh$y+zacs_WWn&18N2 z+%JEB0f3=nzdpQ~zN=QQ2}L90m*oM|^sOkIX~6~Sug#vUiaA~d-+^$qC^MT>38WBo zQg~B9Y3&@@dJN^fGZ4C33dJJSPIljF$OC-Yy*jfzwHA%ha=q^d-WsnVv(06S7Ov=Z z{aZ-ltxYu`3Mx>I9(Uf%8FW&8RJD;#soQw|HtLj06GlKF_UM(6!*_uc$}N1UL(wMo zqs8u4fH_bZ5Xo{5ke)gUhV?~y^sDNLw6*cQ-zsN~_T;MV-m|g?{10l6v?W1qbZ>4T zO<`N0CX?ZSVZ*4w_0yqQ{0RjLb1p-uWnfC%40|pBT z2nPcK1{DYb2?`4Y76JnS0v-VZ7k~f?2@oLA%{&n?%cT{D5B@Kd6OBKCi)p?$>}4so zw!IcYefNr+ql#ba$nm-NxV~}P>7o`CBuO>laIi8)miWwn@%MwUWUp!)^7KSBw1w_$ zm)TDQ)~pZ>k%w= z2d>^JUnZ|cgyi5^+t#@Im)vi-Xo&2ZlV1s39NgN9Q~V8!bhjbXjeNA4|7zW_8cF~M zJV_-da>*7oHyZ#w3qWW~JvM!~W538c*93&}+mslkwW{7S{W>9@XRpxbWDH{*JdS!g zjt+}H0DW;5sj>$m7Y~L`PD(@J#-}0>@0x!;Q^Gd<)rly7EQn%Ht0{+g!j^QMmrB%e z69&NWU&yvx(PVt{l(;nZuaUEI5gVd>u@=yUJNF|ZVojP}o#}n`mq2W4rRtA3Ew!#xy)P_9a7#Rv7Li$5Gahqb231 z80Kp=uhS3pzZxI<>4BNO8-Sd5$)KQ->P;rUAB6LdGs|1BA!!SU?xb7##6VqQBk`k($$2 z+z)UN6iUwL(97Z^>o8*q`EbXA(%6q0TlpvGz`rQzZo^;n5U(zO^5g-;g z?noR*KN$_BjvsW(tWM>6Jf39uO~p%-y){lIp1HKdCvu^DRgd;rOz(qrv}4(fP;jsP zjXE{3Ntt`Rqo?q(K3xT$NSw5pdidt&P}+5AUaSXxO|)iOe1wSOWeY=WO1p0vbm`CH zfT#%L&oG?01Vz{?o_2!dQ@`&dNUmnE(+100I630|NH<{*tPG z-dJGCJ0qr57{&XapIMV*l6Hf2dF5Ui$`5kkY<{qUQdo=IX3hJVD4z1;an!w%XJ%DK zO4_VlL)4$sN6T|FPK)Q&@5nSgs{M4|zo=KNi}0}^j|243fi=wMRip5Xuu)4}l#a(E zu?=b&MnGV-_)FdjzPFBoCU6{4PuO19lZSB1Jx>%N{bTYI5fX*5)fH2`_;S~PqJ``0 zjb}jnO~fzkF6=tw`3r(`INdN1C$5aNrLZjxXYKOtrJ&*2o@CNKW3;Lj!An&Zv?s(| z4KsJmZL~4+P8s5Bh%$5{4W%1kkqq|GAHgyfa!$oT*u(&A2xy(1jS9M6*%Y8J~|qk#pO`LG8-v@9^l&MOgD^xp$B@oR^!5}kbJFQ0;9{e|MtvB zJSDHarU#vOMA)%eAdaFu9CCcb8U#4&)jd0LwUtZuLF&P=OKHd67&^8^DU+rhP9@3y`E!qdsoNf67~~JH_$a2>m5@X`pA@x0 z$^9XmcDa2|Zc~M8B+>i8-enLtEl4=-Y-bN7Dal^i0k(p@q?8qygY>4*#Nj3TnCCGK zrwz?*gKjRru`FM4-c);vV1fmo${IEY6mS1aX~jd7HiChmPpPeQ5rBYdMB418A{`I<(9#_CP}rD4+@; z?g~x>C|Wg^@7&UUT&?b=8tT{&%9*zBBNBvgZ}cpMd;DZElSe))hE@EVa$rT9jd>f> zD=ic=7s~3k#}`k35RfoSy0~#I$flr3M0hC>05`5izazyj!|a~Kn!t>TMX(Ea%hEn9&cv!4S1anV_F6l4bp7Lw06^Pdd&@CmOD3jAHAYaF@^)(G-+P2n!pgTl4h5UtKa^ z=D8EbODq4yiB6H?CzN~#unt>vIgTncB>|7sM4R#TZnGNCvCrA8i*Ml-*Z4f|v054m z+RfG>AokDqBR5nQGSaD12{`OBxbGQDL1s+lCd1AjOuOTwU6E2Z1ZZ|MkZ@6m5mi(1 zDa@whQ(CV$>{G#mOy2+42_hSUk8*09nH#>KlwSYMJT)_whq|LQRLz=($mn-Uz+Ofi zb;hEUn;B{%53TIUC3!k!ncWzP0v`kz0RjLC1p-uWnfC%43;+rV5FpUaJP|R=r6Sc2 z{wp7%3<1pa+8FnLwue|Z1G6{_U81zFM|{^d!bTp`u}fU#%G8U6mpa;gssVnJ*B-vd zm@BAZ_O2w5LueCvRd6;NWLN3=F z2Fe4eIRctq_}b?>d?ZwtReKV++YAFzPDMW?LO^l;M%Gy<*0DZj4e+*)rYZEsL9gB6 zch!Blj=&8@mdyr-#ULPn2g!*V{ju!V1-QjyYb;(Qc=eY+8Mn5j$|1>aygfyH3Q0$s zaH)FwkSNLjV9=zP)U~l=4a|!@93QO8xXT}Ee=M`weGzxqLa{lOH54HS=zSwXq0B0g zD0vwG0HOUl&P20k!j_4O;||`~8F^TnxhEhy4`LO3)-&T8mPdYbTttVUrDAvT@3z5H*7lc^&>L4KHZ7KY1%Fz`950k8r90Iyt9 AiU0rr diff --git a/.github/workflows/deploy-github-release.yaml b/.github/workflows/deploy-github-release.yaml deleted file mode 100644 index f8b28b884..000000000 --- a/.github/workflows/deploy-github-release.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: deploy-github-release -on: - push: - tags: '*' -jobs: - test: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v1 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - distribution: 'temurin' - java-version: '11' - - uses: little-core-labs/get-git-tag@v3.0.2 - - name: deploy-release - run: .buildsystem/deploy-github.sh - env: - GITHUB_MAVEN_USERNAME: ${{ secrets.GITHUB_MAVEN_USERNAME }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} diff --git a/.github/workflows/deploy-sonatype-release.yaml b/.github/workflows/deploy-sonatype-release.yaml deleted file mode 100644 index ac4bcea01..000000000 --- a/.github/workflows/deploy-sonatype-release.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: deploy-sonatype-release -on: - push: - tags: '*' -jobs: - test: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v1 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - distribution: 'temurin' - java-version: '11' - - uses: little-core-labs/get-git-tag@v3.0.2 - - name: deploy-release - run: .buildsystem/deploy-sonatype.sh - env: - SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} diff --git a/.github/workflows/deploy-sonatype-snapshot.yaml b/.github/workflows/deploy-sonatype-snapshot.yaml deleted file mode 100644 index 12950685b..000000000 --- a/.github/workflows/deploy-sonatype-snapshot.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: deploy-sonatype-snapshot -on: - push: - branches: - - master - tags-ignore: - - '*' -jobs: - deploy: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v1 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - distribution: 'temurin' - java-version: '11' - - name: deploy-snapshot - run: bash .buildsystem/deploy-sonatype.sh - env: - SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 000000000..70fa4419f --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,38 @@ +name: Publish GitHub Release +on: + release: + types: [ created ] + +env: + JAVA_VERSION: 17 + JAVA_DISTRO: 'temurin' + +jobs: + publish: + name: Publish to GitHub Packages + runs-on: macos-latest + permissions: + contents: read + packages: write + + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-java@v5 + with: + java-version: ${{ env.JAVA_VERSION }} + distribution: ${{ env.JAVA_DISTRO }} + + - name: Publish to GitHub Packages + run: ./gradlew publishAllPublicationsToGitHubPackagesRepository --no-configuration-cache + env: + GITHUB_ACTOR: ${{ github.actor }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + RELEASE_TAG: ${{ github.event.release.tag_name }} + + - name: Upload build reports + if: failure() + uses: actions/upload-artifact@v6 + with: + name: build-reports + path: '**/build/reports/' + retention-days: 7 From 85a2fc9ecd44a5143aa4b726e0fb5128b2ed6c88 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 04:58:33 +0000 Subject: [PATCH 28/50] docs: add section for updating GitHub workflows --- .github/git-commit-instructions.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/git-commit-instructions.md b/.github/git-commit-instructions.md index c1d7f066a..2a0fc3d25 100644 --- a/.github/git-commit-instructions.md +++ b/.github/git-commit-instructions.md @@ -50,6 +50,10 @@ * `docs: clarify parameter usage in DataStore class` +### Updating Github Workflows + +* `ci: add workflow for automated release on tag` + --- ## Dependency Changes From 23c47b43a2b9eff60325c5b4ddb9351cac0bbd59 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 04:59:52 +0000 Subject: [PATCH 29/50] ci: add lint workflow for code quality checks --- .github/workflows/lint.yaml | 46 +++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/lint.yaml diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 000000000..8d3727df3 --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,46 @@ +name: Run Lint + +on: + pull_request: + paths-ignore: + - '**.md' + - '**.txt' + - '.gitignore' + - 'LICENSE' + - 'docs/**' + - '.github/**' + - '!.github/workflows/**' + - 'renovate.json' + +env: + JAVA_VERSION: 17 + JAVA_DISTRO: 'temurin' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v6 + + - name: Validate Gradle Wrapper + uses: gradle/actions/wrapper-validation@v5 + + - name: Set up JDK 17 + uses: actions/setup-java@v5 + with: + java-version: ${{ env.JAVA_VERSION }} + distribution: ${{ env.JAVA_DISTRO }} + + - name: Set up gradle + uses: gradle/actions/setup-gradle@v5 + + - name: Run Lint + run: | + git fetch origin dev + ./gradlew spotlessCheck From c5813add74aca4fe9097d6e77cab403bf3e161d6 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 05:00:43 +0000 Subject: [PATCH 30/50] ci: add concurrency settings for CI jobs --- .github/workflows/ci.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 40dfcb02d..c1bc173a8 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -11,6 +11,10 @@ env: JAVA_VERSION: 17 JAVA_DISTRO: 'temurin' +concurrency: + group: ${{ github.ref }}-build + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} + jobs: test: runs-on: ubuntu-latest From 7aa5bf1b65b3982806481dd6e79cc50b8687a7a1 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 05:01:13 +0000 Subject: [PATCH 31/50] ci: remove codecov actions from CI workflow --- .github/workflows/ci.yaml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c1bc173a8..8ee1c63d7 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -59,15 +59,6 @@ jobs: name: test-coverage path: test-coverage.zip - - name: codecov unit tests - uses: codecov/codecov-action@v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./adam/build/reports/jacoco/test/jacocoTestReport.xml - flags: unit - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - integration-test: needs: test runs-on: ubuntu-latest @@ -171,13 +162,3 @@ jobs: with: name: logcat-${{ matrix.api }} path: artifacts/logcat.log - - - name: codecov integration tests - if: ${{ !cancelled() }} - uses: codecov/codecov-action@v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./adam/build/reports/jacoco/jacocoIntegrationTestReport/jacocoIntegrationTestReport.xml - flags: integration - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From 566178368d91004cacc8c031c8b269193d260921 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 05:01:29 +0000 Subject: [PATCH 32/50] ci: refactor test result archiving command for clarity --- .github/workflows/ci.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8ee1c63d7..92050e559 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -39,7 +39,9 @@ jobs: - name: archive test results if: failure() - run: (cd adam/build/reports/tests/test; zip -r -X ../../../../../test-result.zip .) + run: | + cd adam/build/reports/tests/test + zip -r -X ../../../../../test-result.zip . - name: Save test output uses: actions/upload-artifact@v6 From 01a011057e2981a0df5032db2f64d58a82a2176c Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 05:05:01 +0000 Subject: [PATCH 33/50] docs: update AGENTS.md with build and test instructions --- AGENTS.md | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 5f6406434..b9749f223 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -3,12 +3,15 @@ ## Build & Test - Build: `./gradlew build` -- Lint: `./gradlew spotlessCheck` (fix: `./gradlew spotlessApply`) +- Assemble only: `./gradlew assemble` +- Lint: `./gradlew spotlessApply` - Run all tests: `./gradlew test` - Run Ktor transport regression tests: `./gradlew :transport-ktor:test --tests "com.malinskiy.adam.transport.ktor.KtorSocketRegressionTest"` -- Purpose: guards Ktor byte-array offset/limit API semantics so Adam `Socket` methods keep length-based behavior during Ktor upgrades. + - Purpose: guards Ktor byte-array offset/limit API semantics so Adam `Socket` methods keep length-based behavior during Ktor upgrades. - Run single test: `./gradlew :adam:test --tests "com.malinskiy.adam.ClassName.testMethod"` - Integration tests: `./gradlew :adam:integrationTest` +- Coverage report: `./gradlew jacocoTestReport` (unit), `./gradlew :adam:jacocoIntegrationTestReport` (integration) +- Generate docs: `./gradlew :adam:dokkaGeneratePublicationHtml` (output: `docs/api/`) ## Architecture @@ -16,14 +19,33 @@ Kotlin coroutine-based ADB (Android Debug Bridge) client library. Modules: - **adam** — Core ADB client (requests, transport, protobuf/gRPC). Main package: `com.malinskiy.adam` - **transport-ktor** — Ktor-based transport implementation -- **android-junit4**, **android-testrunner-contract**, **androidx-screencapture** — Android test instrumentation helpers -- **server/** — Server stubs for testing (JUnit 4 & 5 variants) -- **buildSrc** — Convention plugins (`adam.jvm`, `adam.code.lint`, `adam.android.library`) +- **android-junit4** — Android JUnit4 test rules for adam +- **android-junit4-test-annotation-producer** — Android test annotation producer +- **android-testrunner-contract** — Android test runner contract interfaces +- **androidx-screencapture** — AndroidX screen capture helpers +- **server/** — Server stubs for testing (`server-stub`, `server-stub-junit4`, `server-stub-junit5`) +- **buildSrc** — Convention plugins (`adam.jvm`, `adam.code.lint`, `adam.android.library`) and build logic (`ProjectConfig`, `IntegrationTestConfig`, `MavenPomConfig`, `ProjectExtensions`) + +## Key Dependencies + +- Kotlin 2.3.10, Coroutines 1.10.2 +- Ktor 3.4.0 (network/transport) +- Vert.x 5.0.7 (core, kotlin, coroutines) +- Protobuf 4.33.5 (javalite) + gRPC 1.79.0 +- Android Gradle Plugin 9.0.0 (compileSdk 36, minSdk 24, targetSdk 36) ## Code Style -- Kotlin, JVM target 17. No star imports (star import threshold 999). Max line length 120. -- Formatting: ktlint (IntelliJ IDEA style) via Spotless. Trailing commas allowed. +- Kotlin, JVM target 17. Explicit API mode for library modules. No star imports (star import threshold 999). Max line length 120. +- Formatting: ktlint (IntelliJ IDEA style) via Spotless (`com.diffplug.spotless`). Trailing commas allowed. - Tests use JUnit 4 + assertk + kotlinx.coroutines (`runBlocking`). Server stubs from `:server:server-stub-junit4`. - Apache 2.0 license header required on all source files. - 4-space indent, UTF-8, trailing whitespace trimmed, final newline required. +- Publishing: Vanniktech Maven Publish plugin to GitHub Packages (`com.github.ArthurKun21` group). + +## CI + +- GitHub Actions (`ci.yaml`): runs on push to `dev` and PRs. +- Java 17 (Temurin distribution). +- Unit tests + Ktor transport tests + JaCoCo coverage. +- Integration tests on Android emulator (API levels 24, 34, 35) with AVD caching. From 37065d473d0b9f8773ec2990a91c520da644607f Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 05:17:29 +0000 Subject: [PATCH 34/50] ci: update concurrency settings to include dev branch --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 92050e559..e385d8c62 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -13,7 +13,7 @@ env: concurrency: group: ${{ github.ref }}-build - cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} + cancel-in-progress: ${{ github.ref != 'refs/heads/master' && github.ref != 'refs/heads/dev' }} jobs: test: From 3d2acece57fac94509074ecf2707bccb197a07b6 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 05:17:36 +0000 Subject: [PATCH 35/50] refactor: move java plugin configuration to separate file --- android-testrunner-contract/build.gradle.kts | 15 +-------------- buildSrc/src/main/kotlin/adam.java.gradle.kts | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 14 deletions(-) create mode 100644 buildSrc/src/main/kotlin/adam.java.gradle.kts diff --git a/android-testrunner-contract/build.gradle.kts b/android-testrunner-contract/build.gradle.kts index 102b74672..7f05aea21 100644 --- a/android-testrunner-contract/build.gradle.kts +++ b/android-testrunner-contract/build.gradle.kts @@ -1,5 +1,4 @@ import adam.buildlogic.AdamPublishing -import adam.buildlogic.ProjectConfig import adam.buildlogic.configureAdamPom /* @@ -19,9 +18,8 @@ import adam.buildlogic.configureAdamPom */ plugins { - id("java") + id("adam.java") alias(libs.plugins.vanniktech.maven.publish) - id("adam.code.lint") } mavenPublishing { @@ -33,14 +31,3 @@ mavenPublishing { configureAdamPom() } } - -java { - sourceCompatibility = ProjectConfig.JavaVersion - targetCompatibility = ProjectConfig.JavaVersion -} - -tasks.withType { - compilerOptions { - jvmTarget.set(ProjectConfig.JvmTarget) - } -} diff --git a/buildSrc/src/main/kotlin/adam.java.gradle.kts b/buildSrc/src/main/kotlin/adam.java.gradle.kts new file mode 100644 index 000000000..a71359e9b --- /dev/null +++ b/buildSrc/src/main/kotlin/adam.java.gradle.kts @@ -0,0 +1,17 @@ +import adam.buildlogic.ProjectConfig + +plugins { + id("java") + id("adam.code.lint") +} + +java { + sourceCompatibility = ProjectConfig.JavaVersion + targetCompatibility = ProjectConfig.JavaVersion +} + +tasks.withType { + compilerOptions { + jvmTarget.set(ProjectConfig.JvmTarget) + } +} From 404e0d3dc67a4aa70ad7e2294ec7bc5474757ac9 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 05:22:18 +0000 Subject: [PATCH 36/50] chore(deps): remove adam version from libs.versions.toml --- build.gradle.kts | 2 +- gradle/libs.versions.toml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9c7b23ebf..23384370b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ plugins { version = providers.environmentVariable("RELEASE_TAG") .map { it.removePrefix("v") } - .getOrElse(libs.versions.adam.get()) + .getOrElse("0.1.0") subprojects { version = rootProject.version diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1672f15c9..e59f4d596 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,4 @@ [versions] -adam = "0.5.7" kotlin = "2.3.10" coroutines = "1.10.2" annotations = "26.0.2" From c524a87abaab4063e2daf709438f0030b3ffb870 Mon Sep 17 00:00:00 2001 From: ArthurKun <16458204+ArthurKun21@users.noreply.github.com> Date: Sun, 15 Feb 2026 05:25:00 +0000 Subject: [PATCH 37/50] chore(deps): remove Versions.kt file for environment variable handling --- buildSrc/src/main/kotlin/Versions.kt | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 buildSrc/src/main/kotlin/Versions.kt diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt deleted file mode 100644 index 598e3d298..000000000 --- a/buildSrc/src/main/kotlin/Versions.kt +++ /dev/null @@ -1,3 +0,0 @@ -object Versions { - val adam = System.getenv("GIT_TAG_NAME") ?: "0.5.7" -} From 78a6a5b3f0955eb16531480bb094796fb42cb43a Mon Sep 17 00:00:00 2001 From: Arthur <16458204+ArthurKun21@users.noreply.github.com> Date: Wed, 18 Feb 2026 10:28:18 +0800 Subject: [PATCH 38/50] docs: update AGENTS.md with improved test instructions and formatting --- AGENTS.md | 81 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 16 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index b9749f223..706d584d6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,16 +6,20 @@ - Assemble only: `./gradlew assemble` - Lint: `./gradlew spotlessApply` - Run all tests: `./gradlew test` -- Run Ktor transport regression tests: `./gradlew :transport-ktor:test --tests "com.malinskiy.adam.transport.ktor.KtorSocketRegressionTest"` - - Purpose: guards Ktor byte-array offset/limit API semantics so Adam `Socket` methods keep length-based behavior during Ktor upgrades. - Run single test: `./gradlew :adam:test --tests "com.malinskiy.adam.ClassName.testMethod"` +- Run single test in other modules: `./gradlew :transport-ktor:test --tests "com.malinskiy.adam.transport.ktor.KtorSocketRegressionTest"` +- Ktor transport regression tests: `./gradlew :transport-ktor:test --tests "com.malinskiy.adam.transport.ktor.KtorSocketRegressionTest"` + - Guards Ktor byte-array offset/limit API semantics - Integration tests: `./gradlew :adam:integrationTest` -- Coverage report: `./gradlew jacocoTestReport` (unit), `./gradlew :adam:jacocoIntegrationTestReport` (integration) +- Coverage reports: `./gradlew jacocoTestReport` (unit), `./gradlew :adam:jacocoIntegrationTestReport` (integration) +- Combined coverage: `./gradlew :adam:jacocoCombinedTestReport` - Generate docs: `./gradlew :adam:dokkaGeneratePublicationHtml` (output: `docs/api/`) ## Architecture -Kotlin coroutine-based ADB (Android Debug Bridge) client library. Modules: +Kotlin coroutine-based ADB (Android Debug Bridge) client library. + +### Modules - **adam** — Core ADB client (requests, transport, protobuf/gRPC). Main package: `com.malinskiy.adam` - **transport-ktor** — Ktor-based transport implementation @@ -24,7 +28,14 @@ Kotlin coroutine-based ADB (Android Debug Bridge) client library. Modules: - **android-testrunner-contract** — Android test runner contract interfaces - **androidx-screencapture** — AndroidX screen capture helpers - **server/** — Server stubs for testing (`server-stub`, `server-stub-junit4`, `server-stub-junit5`) -- **buildSrc** — Convention plugins (`adam.jvm`, `adam.code.lint`, `adam.android.library`) and build logic (`ProjectConfig`, `IntegrationTestConfig`, `MavenPomConfig`, `ProjectExtensions`) +- **buildSrc** — Convention plugins and build logic + +### Key Types + +- `AndroidDebugBridgeClient` — Main entry point for ADB communication +- `Request` — Base class for all ADB requests; subclasses: `ComplexRequest`, `AsyncChannelRequest`, `MultiRequest` +- `Socket` — Interface for transport layer (implemented by `KtorSocket`) +- `Target` — Request targeting (HostTarget, DeviceTarget, etc.) ## Key Dependencies @@ -33,19 +44,57 @@ Kotlin coroutine-based ADB (Android Debug Bridge) client library. Modules: - Vert.x 5.0.7 (core, kotlin, coroutines) - Protobuf 4.33.5 (javalite) + gRPC 1.79.0 - Android Gradle Plugin 9.0.0 (compileSdk 36, minSdk 24, targetSdk 36) +- JVM target: 17 ## Code Style -- Kotlin, JVM target 17. Explicit API mode for library modules. No star imports (star import threshold 999). Max line length 120. -- Formatting: ktlint (IntelliJ IDEA style) via Spotless (`com.diffplug.spotless`). Trailing commas allowed. -- Tests use JUnit 4 + assertk + kotlinx.coroutines (`runBlocking`). Server stubs from `:server:server-stub-junit4`. -- Apache 2.0 license header required on all source files. -- 4-space indent, UTF-8, trailing whitespace trimmed, final newline required. -- Publishing: Vanniktech Maven Publish plugin to GitHub Packages (`com.github.ArthurKun21` group). +### Formatting + +- Kotlin, JVM target 17 +- ktlint (IntelliJ IDEA style) via Spotless (`com.diffplug.spotless`) +- 4-space indent, UTF-8, max line length 120 +- Trailing commas allowed +- Trailing whitespace trimmed, final newline required +- Explicit API mode enabled for library modules (`kotlin.explicitApi()`) + +### Imports + +- No star imports (threshold set to 999 to force explicit imports) +- Import aliases for disambiguation: `import io.ktor.network.sockets.Socket as RealKtorSocket` + +### Naming Conventions + +- Classes: PascalCase (e.g., `AndroidDebugBridgeClient`, `ListDevicesRequest`) +- Functions/properties: camelCase (e.g., `execute`, `readElement`, `socketIdleTimeout`) +- Constants: `UPPER_SNAKE_CASE` in companion objects or objects +- Extension functions: placed in `extension/` package (e.g., `Socket.kt` extensions) +- Exception classes: suffix `Exception` (e.g., `RequestRejectedException`, `PushFailedException`) + +### Types + +- Use `public` modifier explicitly (explicit API mode) +- Prefer `suspend` functions for async operations +- Use `Result` or throw exceptions for error handling +- Prefer `ByteBuffer` and `ByteArray` for binary data +- Use Kotlin nullable types (`?`) for optional values + +### Error Handling + +- Custom exceptions extend `RuntimeException` (e.g., `RequestRejectedException`, `RequestValidationException`) +- Request validation uses `ValidationResponse` data class +- Socket operations catch exceptions during cleanup and log them + +### Logging + +- Use `AdamLogging.logger {}` to create a logger +- Log levels: `debug`, `info`, `warn`, `error`, `trace` +- Pattern: `log.debug(e) { "message" }` -## CI +## Testing -- GitHub Actions (`ci.yaml`): runs on push to `dev` and PRs. -- Java 17 (Temurin distribution). -- Unit tests + Ktor transport tests + JaCoCo coverage. -- Integration tests on Android emulator (API levels 24, 34, 35) with AVD caching. +- JUnit 4 with `@Test`, `@Rule` +- assertk for assertions: `assertThat(value).isEqualTo(expected)` +- `runBlocking { }` for coroutine tests +- Server stubs from `:server:server-stub-junit4` for mocking ADB server +- Test naming: `test` (e.g., `testReturnsProperContent`) +- Integration tests in `src/integrationTest/kotlin/` From 357eab7b412c090edf35f290eadda0c0bc135c5e Mon Sep 17 00:00:00 2001 From: Arthur <16458204+ArthurKun21@users.noreply.github.com> Date: Wed, 18 Feb 2026 11:06:10 +0800 Subject: [PATCH 39/50] docs: update comments in ScreenCaptureRequest for clarity on protocol versions --- .../adam/request/framebuffer/ScreenCaptureRequest.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequest.kt b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequest.kt index 0e5b4b297..8d982f329 100644 --- a/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequest.kt +++ b/adam/src/main/kotlin/com/malinskiy/adam/request/framebuffer/ScreenCaptureRequest.kt @@ -35,15 +35,15 @@ public class ScreenCaptureRequest(private val adapter: ScreenCaptureAdapter 12 - // bpp, size, width, height, 4*(length, offset) + // bpp, colorSpace, size, width, height, 4*(length, offset) 2 -> 13 - // bpp, colorSpace, size, width, height, 4*(length, offset) + // compatibility mode: size, width, height. used previously to denote framebuffer depth 16 -> 3 - // compatibility mode: size, width, height. used previously to denote framebuffer depth /** * See https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/master/daemon/framebuffer_service.cpp#42 * for a possible new value for DDMS_RAWIMAGE_VERSION From 957178855e3b8e700b3addd7399848d88e08edb8 Mon Sep 17 00:00:00 2001 From: Arthur <16458204+ArthurKun21@users.noreply.github.com> Date: Wed, 18 Feb 2026 11:09:27 +0800 Subject: [PATCH 40/50] ci: update pull request paths-ignore for improved workflow efficiency --- .github/workflows/ci.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e385d8c62..1cd46aa04 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -5,6 +5,17 @@ on: - master - dev pull_request: + paths-ignore: + - '**/*.md' + - '.github/**.md' + - '.idea/**' + - 'jitpack.yml' + - '**/.gitignore' + - '.vscode/**' + - '**/.editorconfig' + - 'docs/**' + - 'LICENSE' + - 'NOTICE' workflow_dispatch: env: From d2d4370e1deb88c4b5bef009776c62ce11ef2012 Mon Sep 17 00:00:00 2001 From: Arthur <16458204+ArthurKun21@users.noreply.github.com> Date: Wed, 18 Feb 2026 11:09:47 +0800 Subject: [PATCH 41/50] chore: update CODEOWNERS to assign ownership to @ArthurKun21 --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index d32aeef37..b26313391 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1 @@ -* @malinskiy \ No newline at end of file +* @ArthurKun21 \ No newline at end of file From fabc7ad2dbb5a59d6a8ee5355e40141403b0f9d5 Mon Sep 17 00:00:00 2001 From: Arthur <16458204+ArthurKun21@users.noreply.github.com> Date: Wed, 18 Feb 2026 11:13:10 +0800 Subject: [PATCH 42/50] docs: update README to improve structure and add missing links --- README.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ae43ea782..bce19f4c0 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,20 @@ +# adam + +Android Debug Bridge helper written in Kotlin + +## Links + +### Original project + ![Maven Central](https://img.shields.io/maven-central/v/com.malinskiy.adam/adam) -![Codecov](https://img.shields.io/codecov/c/github/Malinskiy/adam) ![Documentation](https://img.shields.io/badge/docs-documentation-green?link=https://malinskiy.github.io/adam/) -# adam -Android Debug Bridge helper written in Kotlin +### JitPack and GitHub Packages + +[![Release](https://jitpack.io/v/ArthurKun21/adam.svg)](https://jitpack.io/#ArthurKun21/adam) ## Motivation + The only way to get access to the adb programmatically from java world currently is to use the ddmlib java project. Unfortunately it has several limitations, namely: 1. Sub-optimal resources usage From c543858ea3bc27a47f382ae827fb01b6b1183cd9 Mon Sep 17 00:00:00 2001 From: Arthur <16458204+ArthurKun21@users.noreply.github.com> Date: Wed, 18 Feb 2026 11:30:42 +0800 Subject: [PATCH 43/50] ci: update GitHub Actions workflow for improved Java setup --- .github/workflows/github-pages.yml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml index 8bc5e6bad..7219933c0 100644 --- a/.github/workflows/github-pages.yml +++ b/.github/workflows/github-pages.yml @@ -5,16 +5,22 @@ on: branches: - master +env: + JAVA_VERSION: 17 + JAVA_DISTRO: 'temurin' + jobs: github-pages: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 + - uses: actions/checkout@v6 + + - name: Set up JDK + uses: actions/setup-java@v5 with: - distribution: 'temurin' - java-version: '11' + java-version: ${{ env.JAVA_VERSION }} + distribution: ${{ env.JAVA_DISTRO }} + - name: Generate dokka files run: ./gradlew :adam:dokkaGenerate - uses: helaili/jekyll-action@2.0.4 From d08388e9c9d9bb57c1217a87f3ebce38e8049f38 Mon Sep 17 00:00:00 2001 From: Arthur <16458204+ArthurKun21@users.noreply.github.com> Date: Wed, 18 Feb 2026 11:35:26 +0800 Subject: [PATCH 44/50] ci: update GitHub Actions workflow for documentation deployment --- .github/workflows/github-pages.yml | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml index 7219933c0..dc4ed3b01 100644 --- a/.github/workflows/github-pages.yml +++ b/.github/workflows/github-pages.yml @@ -5,6 +5,15 @@ on: branches: - master +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: true + env: JAVA_VERSION: 17 JAVA_DISTRO: 'temurin' @@ -14,19 +23,21 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - + - name: Set up JDK uses: actions/setup-java@v5 with: java-version: ${{ env.JAVA_VERSION }} distribution: ${{ env.JAVA_DISTRO }} - + - name: Generate dokka files - run: ./gradlew :adam:dokkaGenerate - - uses: helaili/jekyll-action@2.0.4 - env: - JEKYLL_PAT: ${{ secrets.JEKYLL_PAT }} + run: ./gradlew :adam:dokkaGeneratePublicationHtml + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v4 with: - jekyll_src: docs - target_branch: gh-pages - gem_src: docs + path: docs/api + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 From 742cc7b1729481840705bc006da565ba84cac4ce Mon Sep 17 00:00:00 2001 From: Arthur <16458204+ArthurKun21@users.noreply.github.com> Date: Wed, 18 Feb 2026 11:35:50 +0800 Subject: [PATCH 45/50] ci: update GitHub Actions workflow to trigger on dev branch --- .github/workflows/github-pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml index dc4ed3b01..ec87641bc 100644 --- a/.github/workflows/github-pages.yml +++ b/.github/workflows/github-pages.yml @@ -3,7 +3,7 @@ name: Build and deploy docs on: push: branches: - - master + - dev permissions: contents: read From 2c68276a448e668040e60fe250f6653e7c7facd8 Mon Sep 17 00:00:00 2001 From: Arthur <16458204+ArthurKun21@users.noreply.github.com> Date: Wed, 18 Feb 2026 11:36:10 +0800 Subject: [PATCH 46/50] ci: add pull request trigger to GitHub Actions workflow --- .github/workflows/github-pages.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml index ec87641bc..08190e86d 100644 --- a/.github/workflows/github-pages.yml +++ b/.github/workflows/github-pages.yml @@ -4,6 +4,7 @@ on: push: branches: - dev + pull_request: permissions: contents: read From 43080cc1120228c206acb84e5b1a152c0107f6a5 Mon Sep 17 00:00:00 2001 From: Arthur <16458204+ArthurKun21@users.noreply.github.com> Date: Wed, 18 Feb 2026 11:43:53 +0800 Subject: [PATCH 47/50] ci: update GitHub Actions workflow for GitHub Pages deployment --- .github/workflows/github-pages.yml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml index 08190e86d..450f1f664 100644 --- a/.github/workflows/github-pages.yml +++ b/.github/workflows/github-pages.yml @@ -22,6 +22,9 @@ env: jobs: github-pages: runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} steps: - uses: actions/checkout@v6 @@ -34,10 +37,20 @@ jobs: - name: Generate dokka files run: ./gradlew :adam:dokkaGeneratePublicationHtml + - name: Setup Pages + uses: actions/configure-pages@v5 + + - name: Build Jekyll site + uses: actions/jekyll-build-pages@v1 + with: + source: docs + destination: ./_site + + - name: Copy Dokka API docs into site + run: cp -r docs/api _site/api + - name: Upload Pages artifact uses: actions/upload-pages-artifact@v4 - with: - path: docs/api - name: Deploy to GitHub Pages id: deployment From f9dd299b768478c6d4eb393448d41914c20f124a Mon Sep 17 00:00:00 2001 From: Arthur <16458204+ArthurKun21@users.noreply.github.com> Date: Wed, 18 Feb 2026 11:45:41 +0800 Subject: [PATCH 48/50] ci: remove environment configuration from GitHub Pages workflow --- .github/workflows/github-pages.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml index 450f1f664..b8395b78d 100644 --- a/.github/workflows/github-pages.yml +++ b/.github/workflows/github-pages.yml @@ -22,9 +22,6 @@ env: jobs: github-pages: runs-on: ubuntu-latest - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} steps: - uses: actions/checkout@v6 From d1e9ee8545583e876ad7841b6582caf80246e890 Mon Sep 17 00:00:00 2001 From: Arthur <16458204+ArthurKun21@users.noreply.github.com> Date: Wed, 18 Feb 2026 11:49:51 +0800 Subject: [PATCH 49/50] ci: rename workflow from 'Build and deploy docs' to 'Docs' --- .github/workflows/github-pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml index b8395b78d..9f2796d74 100644 --- a/.github/workflows/github-pages.yml +++ b/.github/workflows/github-pages.yml @@ -1,4 +1,4 @@ -name: Build and deploy docs +name: Docs on: push: From 58366788164843e9994804c744018e3e7d802852 Mon Sep 17 00:00:00 2001 From: Arthur <16458204+ArthurKun21@users.noreply.github.com> Date: Wed, 18 Feb 2026 11:59:09 +0800 Subject: [PATCH 50/50] ci: update GitHub Actions workflow to trigger on master branch --- .github/workflows/github-pages.yml | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml index 9f2796d74..65564197e 100644 --- a/.github/workflows/github-pages.yml +++ b/.github/workflows/github-pages.yml @@ -3,8 +3,8 @@ name: Docs on: push: branches: - - dev - pull_request: + - master + # pull_request: permissions: contents: read @@ -34,20 +34,10 @@ jobs: - name: Generate dokka files run: ./gradlew :adam:dokkaGeneratePublicationHtml - - name: Setup Pages - uses: actions/configure-pages@v5 - - - name: Build Jekyll site - uses: actions/jekyll-build-pages@v1 - with: - source: docs - destination: ./_site - - - name: Copy Dokka API docs into site - run: cp -r docs/api _site/api - - name: Upload Pages artifact uses: actions/upload-pages-artifact@v4 + with: + path: docs/api - name: Deploy to GitHub Pages id: deployment