Skip to content

Commit

Permalink
test(test): tests tests tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Malinskiy committed May 12, 2020
1 parent 77d6125 commit 946ad05
Show file tree
Hide file tree
Showing 32 changed files with 970 additions and 167 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ package com.malinskiy.adam.integration
import assertk.assertThat
import assertk.assertions.contains
import assertk.assertions.doesNotContain
import com.malinskiy.adam.request.pm.Package
import com.malinskiy.adam.request.pm.PmListRequest
import com.malinskiy.adam.request.sync.InstallRemotePackageRequest
import com.malinskiy.adam.request.sync.PushFileRequest
import com.malinskiy.adam.request.sync.UninstallRemotePackageRequest
import com.malinskiy.adam.request.sync.*
import com.malinskiy.adam.rule.AdbDeviceRule
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.runBlocking
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import com.malinskiy.adam.Const
import com.malinskiy.adam.log.AdamLogging

class DiscoverAdbSocketInteractor {
private val TAG = DiscoverAdbSocketInteractor::class.java.simpleName

fun execute() = discover("system property") { System.getProperty(Const.SERVER_PORT_ENV_VAR) }
?: discover("env var") { System.getenv(Const.SERVER_PORT_ENV_VAR) }
?: Const.DEFAULT_ADB_PORT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ sealed class LocalPortSpec {
}
}

class LocalTcpPortSpec(val port: Int) : LocalPortSpec() {
data class LocalTcpPortSpec(val port: Int) : LocalPortSpec() {
override fun toSpec() = "tcp:$port"
}

class LocalUnixSocketPortSpec(val path: String) : LocalPortSpec() {
data class LocalUnixSocketPortSpec(val path: String) : LocalPortSpec() {
override fun toSpec() = "local:$path"
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,26 @@ sealed class RemotePortSpec {
}
}

class RemoteTcpPortSpec(val port: Int) : RemotePortSpec() {
data class RemoteTcpPortSpec(val port: Int) : RemotePortSpec() {
override fun toSpec() = "tcp:$port"
}

class RemoteAbstractPortSpec(val unixDomainSocketName: String) : RemotePortSpec() {
data class RemoteAbstractPortSpec(val unixDomainSocketName: String) : RemotePortSpec() {
override fun toSpec() = "localabstract:$unixDomainSocketName"
}

class RemoteReservedPortSpec(val unixDomainSocketName: String) : RemotePortSpec() {
data class RemoteReservedPortSpec(val unixDomainSocketName: String) : RemotePortSpec() {
override fun toSpec() = "localreserved:$unixDomainSocketName"
}

class RemoteFilesystemPortSpec(val unixDomainSocketName: String) : RemotePortSpec() {
data class RemoteFilesystemPortSpec(val unixDomainSocketName: String) : RemotePortSpec() {
override fun toSpec() = "localfilesystem:$unixDomainSocketName"
}

class RemoteDevPortSpec(val charDeviceName: String): RemotePortSpec() {
data class RemoteDevPortSpec(val charDeviceName: String) : RemotePortSpec() {
override fun toSpec() = "dev:$charDeviceName"
}

class JDWPPortSpec(val processId: Int): RemotePortSpec() {
data class JDWPPortSpec(val processId: Int) : RemotePortSpec() {
override fun toSpec() = "jdwp:$processId"
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 Anton Malinskiy
* Copyright (C) 2020 Anton Malinskiy
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,10 +14,9 @@
* limitations under the License.
*/

package com.malinskiy.adam.request.pm
package com.malinskiy.adam.request.sync

import com.malinskiy.adam.Const
import com.malinskiy.adam.request.sync.SyncShellCommandRequest

class PmListRequest(val includePath: Boolean = false) : SyncShellCommandRequest<List<Package>>(
cmd = StringBuilder().apply {
Expand Down
138 changes: 138 additions & 0 deletions src/main/kotlin/com/malinskiy/adam/request/sync/RawImage.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
* Copyright (C) 2020 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.request.sync

import com.malinskiy.adam.exception.UnsupportedImageProtocolException
import java.awt.image.BufferedImage
import java.nio.ByteBuffer

data class RawImage(
val version: Int,
val bitsPerPixel: Int,
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
) {

fun getARGB(index: Int): Int {
var value: Int
val r: Int
val g: Int
val b: Int
val a: Int
if (bitsPerPixel == 16) {
value = buffer[index].toInt() and 0x00FF
value = value or (buffer[index + 1].toInt() shl 8 and 0x0FF00)
// RGB565 to RGB888
// Multiply by 255/31 to convert from 5 bits (31 max) to 8 bits (255)
r = (value.ushr(11) and 0x1f) * 255 / 31
g = (value.ushr(5) and 0x3f) * 255 / 63
b = (value and 0x1f) * 255 / 31
a = 0xFF // force alpha to opaque if there's no alpha value in the framebuffer.
} else if (bitsPerPixel == 32) {
value = buffer[index].toInt() and 0x00FF
value = value or (buffer[index + 1].toInt() and 0x00FF shl 8)
value = value or (buffer[index + 2].toInt() and 0x00FF shl 16)
value = value or (buffer[index + 3].toInt() and 0x00FF shl 24)
r = value.ushr(redOffset) and getMask(redLength) shl 8 - redLength
g = value.ushr(greenOffset) and getMask(greenLength) shl 8 - greenLength
b = value.ushr(blueOffset) and getMask(blueLength) shl 8 - blueLength
a = value.ushr(alphaOffset) and getMask(alphaLength) shl 8 - alphaLength
} else {
throw UnsupportedOperationException("RawImage.getARGB(int) only works in 16 and 32 bit mode.")
}

return a shl 24 or (r shl 16) or (g shl 8) or b
}

private fun getMask(length: Int): Int {
return (1 shl length) - 1
}

fun toBufferedImage(): BufferedImage {
val image =
BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB)

var index = 0
val bytesPerPixel = bitsPerPixel shr 3
for (y in 0 until height) {
for (x in 0 until width) {
image.setRGB(x, y, getARGB(index) or -0x1000000)
index += bytesPerPixel
}
}
return image
}

companion object {
private fun ByteBuffer.moveToByteArray(): ByteArray {
rewind()
val array = ByteArray(remaining())
get(array)
return array
}

fun from(version: Int, bytes: ByteBuffer, imageBuffer: ByteBuffer): RawImage {
return when (version) {
16 ->
RawImage(
version = version,
bitsPerPixel = bytes.int,
size = bytes.int,
width = bytes.int,
height = bytes.int,
redOffset = 11,
redLength = 5,
greenOffset = 5,
greenLength = 6,
blueOffset = 0,
blueLength = 5,
alphaOffset = 0,
alphaLength = 0,
buffer = imageBuffer.moveToByteArray()
)
1 -> RawImage(
version = version,
bitsPerPixel = bytes.int,
size = bytes.int,
width = bytes.int,
height = bytes.int,
redOffset = bytes.int,
redLength = bytes.int,
blueOffset = bytes.int,
blueLength = bytes.int,
greenOffset = bytes.int,
greenLength = bytes.int,
alphaOffset = bytes.int,
alphaLength = bytes.int,
buffer = imageBuffer.moveToByteArray()
)
else -> throw UnsupportedImageProtocolException(version)
}

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,12 @@ class ScreenCaptureRequest : ComplexRequest<RawImage>() {
val protocolVersion = protocolBuffer.order(ByteOrder.LITTLE_ENDIAN).int
val headerSize = when (protocolVersion) {
1 -> 12 // bpp, size, width, height, 4*(length, offset)
16 -> 3 // compatibility mode: size, width, height
16 -> 3 // compatibility mode: size, width, height. used previously to denote framebuffer depth
else -> throw UnsupportedImageProtocolException(protocolVersion)
}
val headerBuffer = ByteBuffer.allocate(headerSize * 4)
readChannel.readFully(headerBuffer)
headerBuffer.rewind()

writeChannel.writeFully(ByteArray(1) { 0.toByte() }, 0, 1)

headerBuffer.order(ByteOrder.LITTLE_ENDIAN)
Expand All @@ -47,111 +46,8 @@ class ScreenCaptureRequest : ComplexRequest<RawImage>() {
val imageBuffer = ByteBuffer.allocate(imageSize)
headerBuffer.rewind()
readChannel.readFully(imageBuffer)

return RawImage.from(protocolVersion, headerBuffer, imageBuffer)
}

override fun serialize() = createBaseRequest("framebuffer:")
}

data class RawImage(
val version: Int,
val bitsPerPixel: Int,
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
) {

fun getARGB(index: Int): Int {
var value: Int
val r: Int
val g: Int
val b: Int
val a: Int
if (bitsPerPixel == 16) {
value = buffer[index].toInt() and 0x00FF
value = value or (buffer[index + 1].toInt() shl 8 and 0x0FF00)
// RGB565 to RGB888
// Multiply by 255/31 to convert from 5 bits (31 max) to 8 bits (255)
r = (value.ushr(11) and 0x1f) * 255 / 31
g = (value.ushr(5) and 0x3f) * 255 / 63
b = (value and 0x1f) * 255 / 31
a = 0xFF // force alpha to opaque if there's no alpha value in the framebuffer.
} else if (bitsPerPixel == 32) {
value = buffer[index].toInt() and 0x00FF
value = value or (buffer[index + 1].toInt() and 0x00FF shl 8)
value = value or (buffer[index + 2].toInt() and 0x00FF shl 16)
value = value or (buffer[index + 3].toInt() and 0x00FF shl 24)
r = value.ushr(redOffset) and getMask(redLength) shl 8 - redLength
g = value.ushr(greenOffset) and getMask(greenLength) shl 8 - greenLength
b = value.ushr(blueOffset) and getMask(blueLength) shl 8 - blueLength
a = value.ushr(alphaOffset) and getMask(alphaLength) shl 8 - alphaLength
} else {
throw UnsupportedOperationException("RawImage.getARGB(int) only works in 16 and 32 bit mode.")
}

return a shl 24 or (r shl 16) or (g shl 8) or b
}

private fun getMask(length: Int): Int {
return (1 shl length) - 1
}

companion object {
private fun ByteBuffer.moveToByteArray(): ByteArray {
rewind()
val array = ByteArray(remaining())
get(array)
return array
}

fun from(version: Int, bytes: ByteBuffer, imageBuffer: ByteBuffer): RawImage {
return when (version) {
16 ->
RawImage(
version = version,
bitsPerPixel = bytes.int,
size = bytes.int,
width = bytes.int,
height = bytes.int,
redOffset = 11,
redLength = 5,
greenOffset = 5,
greenLength = 6,
blueOffset = 0,
blueLength = 5,
alphaOffset = 0,
alphaLength = 0,
buffer = imageBuffer.moveToByteArray()
)
1 -> RawImage(
version = version,
bitsPerPixel = bytes.int,
size = bytes.int,
width = bytes.int,
height = bytes.int,
redOffset = bytes.int,
redLength = bytes.int,
blueOffset = bytes.int,
blueLength = bytes.int,
greenOffset = bytes.int,
greenLength = bytes.int,
alphaOffset = bytes.int,
alphaLength = bytes.int,
buffer = imageBuffer.moveToByteArray()
)
else -> throw UnsupportedImageProtocolException(version)
}

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,13 @@ class SyncLogcatRequest(
) : SyncShellCommandRequest<String>(
cmd = "logcat" +
" -d" +
"${
since?.let {
(since?.let {
" -t ${since.toEpochMilli()}.0"
} ?: ""
}" +
} ?: "") +
" ${modes.joinToString(separator = " ") { "-v $it" }}" +
" ${buffers.joinToString(separator = " ") { "-b $it" }}" +
"${pid?.let { " --pid=$it" } ?: ""}" +
"${lastReboot?.let { " -L" } ?: ""}" +
(pid?.let { " --pid=$it" } ?: "") +
(lastReboot?.let { " -L" } ?: "") +
" ${filters.joinToString(separator = " ") { "${it.tag}:${it.level.name}" }}"
.trimEnd()
), ResponseTransformer<String> by StringResponseTransformer()
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import com.malinskiy.adam.request.transform.StringResponseTransformer
* @param keepData keep the data and cache directories around after package removal
*/
class UninstallRemotePackageRequest(
val packageName: String,
val keepData: Boolean = false
packageName: String,
keepData: Boolean = false
) : SyncShellCommandRequest<String>(
cmd = StringBuilder().apply {
append("pm uninstall ")
Expand Down
Loading

0 comments on commit 946ad05

Please sign in to comment.