Issue #84: support misc.img
Actions: unpack pack pull flash Signed-off-by: cfig <yuyezhong@gmail.com>pull/94/head
parent
54be7a4fae
commit
f716e34d6d
@ -1,135 +0,0 @@
|
||||
// Copyright 2021 yuyezhong@gmail.com
|
||||
//
|
||||
// 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 cfig.bcb
|
||||
|
||||
import cc.cfig.io.Struct
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.lang.IllegalStateException
|
||||
|
||||
data class BootloaderMsg(//offset 0, size 2k
|
||||
var command: String = "",
|
||||
var status: String = "",
|
||||
var recovery: String = "",
|
||||
var stage: String = "",
|
||||
var reserved: ByteArray = byteArrayOf()
|
||||
) {
|
||||
companion object {
|
||||
private const val FORMAT_STRING = "32s32s768s32s1184b"
|
||||
const val miscFile = "misc.file"
|
||||
const val SIZE = 2048
|
||||
private val log = LoggerFactory.getLogger("BootloaderMsg")
|
||||
|
||||
init {
|
||||
assert(SIZE == Struct(FORMAT_STRING).calcSize())
|
||||
}
|
||||
}
|
||||
|
||||
constructor(fis: FileInputStream) : this() {
|
||||
val info = Struct(FORMAT_STRING).unpack(fis)
|
||||
this.command = info[0] as String
|
||||
this.status = info[1] as String
|
||||
this.recovery = info[2] as String
|
||||
this.stage = info[3] as String
|
||||
this.reserved = info[4] as ByteArray
|
||||
}
|
||||
|
||||
fun encode(): ByteArray {
|
||||
return Struct(FORMAT_STRING).pack(
|
||||
this.command,
|
||||
this.stage,
|
||||
this.recovery,
|
||||
this.stage,
|
||||
byteArrayOf())
|
||||
}
|
||||
|
||||
fun clearBootloaderMessage() {
|
||||
val boot = BootloaderMsg()
|
||||
boot.writeBootloaderMessage()
|
||||
}
|
||||
|
||||
fun writeBootloaderMessage(options: Array<String>) {
|
||||
this.updateBootloaderMessageInStruct(options)
|
||||
this.writeBootloaderMessage()
|
||||
}
|
||||
|
||||
fun readBootloaderMsg() {
|
||||
if (File(miscFile).exists()) {
|
||||
log.info("readBootloaderMsg() from $miscFile")
|
||||
val fis = FileInputStream(miscFile)
|
||||
val info = Struct(FORMAT_STRING).unpack(fis)
|
||||
this.command = info[0] as String
|
||||
this.status = info[1] as String
|
||||
this.recovery = info[2] as String
|
||||
this.stage = info[3] as String
|
||||
this.reserved = info[4] as ByteArray
|
||||
fis.close()
|
||||
} else {
|
||||
log.info("$miscFile missing")
|
||||
}
|
||||
}
|
||||
|
||||
fun writeRebootBootloader() {
|
||||
if (this.command.isNotBlank()) {
|
||||
throw IllegalStateException("Bootloader command pending.")
|
||||
}
|
||||
this.command = "bootonce-bootloader"
|
||||
writeBootloaderMessage()
|
||||
}
|
||||
|
||||
fun writeBootloaderMessage() {
|
||||
log.info("writing ... $this")
|
||||
if (!File(miscFile).exists()) {
|
||||
File(miscFile).createNewFile()
|
||||
}
|
||||
FileOutputStream(miscFile, false).use { fos ->
|
||||
fos.write(this.encode())
|
||||
}
|
||||
}
|
||||
|
||||
fun updateBootloaderMessageInStruct(options: Array<String>) {
|
||||
this.command = "boot-recovery"
|
||||
this.recovery = "recovery\n"
|
||||
options.forEach {
|
||||
this.recovery += if (it.endsWith("\n")) {
|
||||
it
|
||||
} else {
|
||||
it + "\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateBootloaderMessage(command: String, recovery: String, options: Array<String>?) {
|
||||
this.command = command
|
||||
this.recovery = "$recovery\n"
|
||||
options?.forEach {
|
||||
this.recovery += if (it.endsWith("\n")) {
|
||||
it
|
||||
} else {
|
||||
it + "\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
https://android-review.googlesource.com/c/platform/bootable/recovery/+/735984
|
||||
*/
|
||||
fun updateBootFastboot() {
|
||||
this.command = "boot-fastboot"
|
||||
this.recovery = ""
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
// Copyright 2021 yuyezhong@gmail.com
|
||||
//
|
||||
// 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 cfig.bcb
|
||||
|
||||
import cc.cfig.io.Struct
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.FileInputStream
|
||||
|
||||
class BootloaderMsgAB( //offset 2k, size 2k
|
||||
var slotSuffix: String = "",
|
||||
var updateChannel: String = "",
|
||||
var reserved: ByteArray = byteArrayOf()
|
||||
) {
|
||||
companion object {
|
||||
private const val FORMAT_STRING = "32s128s1888b"
|
||||
const val SIZE = 2048
|
||||
private val log = LoggerFactory.getLogger(BootloaderMsgAB::class.java.simpleName)
|
||||
|
||||
init {
|
||||
assert(SIZE == Struct(FORMAT_STRING).calcSize())
|
||||
}
|
||||
}
|
||||
|
||||
constructor(fis: FileInputStream) : this() {
|
||||
val info = Struct(FORMAT_STRING).unpack(fis)
|
||||
this.slotSuffix = info[0] as String
|
||||
this.updateChannel = info[1] as String
|
||||
this.reserved = info[2] as ByteArray
|
||||
}
|
||||
|
||||
fun encode(): ByteArray {
|
||||
return Struct(FORMAT_STRING).pack(
|
||||
this.slotSuffix,
|
||||
this.updateChannel,
|
||||
byteArrayOf())
|
||||
}
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
// Copyright 2021 yuyezhong@gmail.com
|
||||
//
|
||||
// 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 cfig.bcb
|
||||
|
||||
import cc.cfig.io.Struct
|
||||
import cfig.helper.Helper
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.FileInputStream
|
||||
|
||||
data class VirtualABMsg(
|
||||
var version: Int = 0,
|
||||
var magic: ByteArray = byteArrayOf(),
|
||||
var mergeStatus: Int = 0,
|
||||
var sourceSlot: Int = 0,
|
||||
var reserved: ByteArray = byteArrayOf()
|
||||
) {
|
||||
companion object {
|
||||
private const val FORMAT_STRING = "b4bbb57b"
|
||||
const val SIZE = 64
|
||||
private val log = LoggerFactory.getLogger("VirtualABMsg")
|
||||
private const val MAGIC = "b00a7456"
|
||||
|
||||
init {
|
||||
assert(SIZE == Struct(FORMAT_STRING).calcSize())
|
||||
}
|
||||
}
|
||||
|
||||
constructor(fis: FileInputStream) : this() {
|
||||
val info = Struct(FORMAT_STRING).unpack(fis)
|
||||
this.version = (info[0] as ByteArray)[0].toInt()
|
||||
this.magic = info[1] as ByteArray
|
||||
this.mergeStatus = (info[2] as ByteArray)[0].toInt()
|
||||
this.sourceSlot = (info[3] as ByteArray)[0].toInt()
|
||||
this.reserved = info[4] as ByteArray
|
||||
if (MAGIC != Helper.Companion.toHexString(this.magic)) {
|
||||
throw IllegalArgumentException("stream is not VirtualAB message")
|
||||
}
|
||||
}
|
||||
|
||||
fun encode(): ByteArray {
|
||||
return Struct(FORMAT_STRING).pack(
|
||||
this.version,
|
||||
this.magic,
|
||||
this.mergeStatus,
|
||||
this.sourceSlot,
|
||||
0
|
||||
)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "VABMsg(v=$version, magic=${Helper.toHexString(magic)}, mergeStatus=$mergeStatus:${MergeStatus.values().get(this.mergeStatus)}, sourceSlot=$sourceSlot)"
|
||||
}
|
||||
|
||||
|
||||
enum class MergeStatus(val status: Int) {
|
||||
NONE(0),
|
||||
UNKNOWN(1),
|
||||
SNAPSHOTTED(2),
|
||||
MERGING(3),
|
||||
CANCELLED(4)
|
||||
}
|
||||
}
|
@ -0,0 +1,231 @@
|
||||
package miscimg
|
||||
|
||||
import cc.cfig.io.Struct
|
||||
import cfig.helper.Helper
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.FileInputStream
|
||||
|
||||
data class MiscImage(
|
||||
var bcb: BootloaderMessage = BootloaderMessage(),
|
||||
var virtualAB: VirtualABMessage? = null
|
||||
) {
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(MiscImage::class.java)
|
||||
private val mapper = ObjectMapper()
|
||||
private val workDir = Helper.prop("workDir")
|
||||
|
||||
fun parse(fileName: String): MiscImage {
|
||||
val ret = MiscImage()
|
||||
FileInputStream(fileName).use { fis ->
|
||||
ret.bcb = BootloaderMessage(fis)
|
||||
}
|
||||
FileInputStream(fileName).use { fis ->
|
||||
fis.skip(32 * 1024)
|
||||
try {
|
||||
ret.virtualAB = VirtualABMessage(fis)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
log.info(e.toString())
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
}
|
||||
|
||||
//offset 0, size 2k
|
||||
data class BootloaderMessage(
|
||||
var command: String = "",
|
||||
var status: String = "",
|
||||
var recovery: String = "",
|
||||
var stage: String = "",
|
||||
var reserved: ByteArray = byteArrayOf()
|
||||
) {
|
||||
constructor(fis: FileInputStream) : this() {
|
||||
val info = Struct(FORMAT_STRING).unpack(fis)
|
||||
this.command = info[0] as String
|
||||
this.status = info[1] as String
|
||||
this.recovery = info[2] as String
|
||||
this.stage = info[3] as String
|
||||
//this.reserved = info[4] as ByteArray
|
||||
}
|
||||
|
||||
fun encode(): ByteArray {
|
||||
return Struct(FORMAT_STRING).pack(
|
||||
this.command,
|
||||
this.stage,
|
||||
this.recovery,
|
||||
this.stage,
|
||||
byteArrayOf()
|
||||
)
|
||||
}
|
||||
|
||||
fun updateBootloaderMessageInStruct(options: Array<String>) {
|
||||
this.command = "boot-recovery"
|
||||
this.recovery = "recovery\n"
|
||||
options.forEach {
|
||||
this.recovery += if (it.endsWith("\n")) {
|
||||
it
|
||||
} else {
|
||||
it + "\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateBootloaderMessage(command: String, recovery: String, options: Array<String>?) {
|
||||
this.command = command
|
||||
this.recovery = "$recovery\n"
|
||||
options?.forEach {
|
||||
this.recovery += if (it.endsWith("\n")) {
|
||||
it
|
||||
} else {
|
||||
it + "\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val FORMAT_STRING = "32s32s768s32s1184b"
|
||||
private val log = LoggerFactory.getLogger(BootloaderMessage::class.java)
|
||||
const val SIZE = 2048
|
||||
|
||||
init {
|
||||
assert(SIZE == Struct(FORMAT_STRING).calcSize())
|
||||
}
|
||||
|
||||
/*
|
||||
https://android-review.googlesource.com/c/platform/bootable/recovery/+/735984
|
||||
*/
|
||||
fun rebootFastboot1(): BootloaderMessage {
|
||||
return BootloaderMessage().apply {
|
||||
command = "boot-fastboot"
|
||||
}
|
||||
}
|
||||
|
||||
fun rebootFastboot2(): BootloaderMessage {
|
||||
return BootloaderMessage().apply {
|
||||
updateBootloaderMessageInStruct(arrayOf("--fastboot"))
|
||||
}
|
||||
}
|
||||
|
||||
fun rebootBootloader(): BootloaderMessage {
|
||||
return BootloaderMessage().apply {
|
||||
command = "bootonce-bootloader"
|
||||
}
|
||||
}
|
||||
|
||||
fun rebootRecovery(): BootloaderMessage {
|
||||
return BootloaderMessage().apply {
|
||||
this.updateBootloaderMessageInStruct(arrayOf())
|
||||
}
|
||||
}
|
||||
|
||||
fun rebootCrash(): BootloaderMessage {
|
||||
return BootloaderMessage().apply {
|
||||
//@formatter:off
|
||||
updateBootloaderMessageInStruct(arrayOf(
|
||||
"--prompt_and_wipe_data",
|
||||
"--reason=RescueParty",
|
||||
"--locale=en_US"))
|
||||
//@formatter:on
|
||||
}
|
||||
}
|
||||
|
||||
fun rebootOTA(): BootloaderMessage {
|
||||
return BootloaderMessage().apply {
|
||||
updateBootloaderMessageInStruct(arrayOf("--update_package=/cache/update.zip", "--security"))
|
||||
}
|
||||
}
|
||||
|
||||
fun rebootWipeData(): BootloaderMessage {
|
||||
return BootloaderMessage().apply {
|
||||
//@formatter:off
|
||||
updateBootloaderMessageInStruct(arrayOf(
|
||||
"--wipe_data",
|
||||
"--reason=convert_fbe",
|
||||
"--locale=en_US"))
|
||||
//@formatter:on
|
||||
}
|
||||
}
|
||||
|
||||
fun rebootWipeAb(): BootloaderMessage {
|
||||
return BootloaderMessage().apply {
|
||||
//@formatter:off
|
||||
updateBootloaderMessageInStruct(arrayOf(
|
||||
"--wipe_ab",
|
||||
"--wipe_package_size=1024",
|
||||
"--locale=en_US"))
|
||||
//@formatter:on
|
||||
}
|
||||
}
|
||||
|
||||
fun generateSamples(): MutableList<BootloaderMessage> {
|
||||
return mutableListOf(
|
||||
rebootFastboot1(),
|
||||
rebootFastboot2(),
|
||||
rebootBootloader(),
|
||||
rebootRecovery(),
|
||||
rebootCrash(),
|
||||
rebootOTA(),
|
||||
rebootWipeData(),
|
||||
rebootWipeAb()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//offset 32KB, size 64B
|
||||
data class VirtualABMessage(
|
||||
var version: Int = 0,
|
||||
var magic: ByteArray = byteArrayOf(),
|
||||
var mergeStatus: Int = 0,
|
||||
var sourceSlot: Int = 0,
|
||||
var reserved: ByteArray = byteArrayOf()
|
||||
) {
|
||||
companion object {
|
||||
private const val FORMAT_STRING = "b4bbb57b"
|
||||
private val log = LoggerFactory.getLogger("VirtualABMsg")
|
||||
private const val MAGIC = "b00a7456"
|
||||
const val SIZE = 64
|
||||
|
||||
init {
|
||||
assert(SIZE == Struct(FORMAT_STRING).calcSize())
|
||||
}
|
||||
}
|
||||
|
||||
constructor(fis: FileInputStream) : this() {
|
||||
val info = Struct(FORMAT_STRING).unpack(fis)
|
||||
this.version = (info[0] as ByteArray)[0].toInt()
|
||||
this.magic = info[1] as ByteArray
|
||||
this.mergeStatus = (info[2] as ByteArray)[0].toInt()
|
||||
this.sourceSlot = (info[3] as ByteArray)[0].toInt()
|
||||
this.reserved = info[4] as ByteArray
|
||||
if (MAGIC != Helper.Companion.toHexString(this.magic)) {
|
||||
throw IllegalArgumentException("stream is not VirtualAB message")
|
||||
}
|
||||
}
|
||||
|
||||
fun encode(): ByteArray {
|
||||
return Struct(FORMAT_STRING).pack(
|
||||
byteArrayOf(this.version.toByte()),
|
||||
this.magic,
|
||||
byteArrayOf(this.mergeStatus.toByte()),
|
||||
byteArrayOf(this.sourceSlot.toByte()),
|
||||
byteArrayOf(0)
|
||||
)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "VABMsg(v=$version, magic=${Helper.toHexString(magic)}, mergeStatus=$mergeStatus:${
|
||||
MergeStatus.values().get(this.mergeStatus)
|
||||
}, sourceSlot=$sourceSlot)"
|
||||
}
|
||||
|
||||
enum class MergeStatus(val status: Int) {
|
||||
NONE(0),
|
||||
UNKNOWN(1),
|
||||
SNAPSHOTTED(2),
|
||||
MERGING(3),
|
||||
CANCELLED(4)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
// Copyright 2022 yuyezhong@gmail.com
|
||||
//
|
||||
// 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 cfig.packable
|
||||
|
||||
import cc.cfig.io.Struct
|
||||
import miscimg.MiscImage
|
||||
import cfig.helper.Helper.Companion.deleteIfExists
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.RandomAccessFile
|
||||
|
||||
class MiscImgParser : IPackable {
|
||||
override val loopNo: Int
|
||||
get() = 0
|
||||
|
||||
override fun capabilities(): List<String> {
|
||||
return listOf("^misc\\.img$")
|
||||
}
|
||||
|
||||
override fun unpack(fileName: String) {
|
||||
cleanUp()
|
||||
val misc = MiscImage.parse(fileName)
|
||||
log.info(misc.toString())
|
||||
ObjectMapper().writerWithDefaultPrettyPrinter()
|
||||
.writeValue(File(File(fileName).name.removeSuffix(".img") + ".json"), misc)
|
||||
ObjectMapper().writerWithDefaultPrettyPrinter().writeValue(
|
||||
File("sample.json"),
|
||||
MiscImage.BootloaderMessage.generateSamples()
|
||||
)
|
||||
}
|
||||
|
||||
override fun pack(fileName: String) {
|
||||
val misc = ObjectMapper().readValue(
|
||||
File(File(fileName).name.removeSuffix(".img") + ".json"),
|
||||
MiscImage::class.java
|
||||
)
|
||||
val out = File("$fileName.new")
|
||||
File(fileName).copyTo(out, true)
|
||||
RandomAccessFile(out.name, "rw").use { raf ->
|
||||
raf.write(misc.bcb.encode())
|
||||
raf.seek(32 * 1024)
|
||||
if (misc.virtualAB != null) {
|
||||
raf.write(misc.virtualAB!!.encode())
|
||||
}
|
||||
}
|
||||
log.info("${out.name} is ready")
|
||||
}
|
||||
|
||||
override fun flash(fileName: String, deviceName: String) {
|
||||
val stem = fileName.substring(0, fileName.indexOf("."))
|
||||
super.flash("$fileName.new", stem)
|
||||
}
|
||||
|
||||
override fun `@verify`(fileName: String) {
|
||||
super.`@verify`(fileName)
|
||||
}
|
||||
|
||||
override fun pull(fileName: String, deviceName: String) {
|
||||
super.pull(fileName, deviceName)
|
||||
}
|
||||
|
||||
fun clean(fileName: String) {
|
||||
super.cleanUp()
|
||||
listOf("", ".clear", ".google", ".clear", ".signed", ".signed2").forEach {
|
||||
"$fileName$it".deleteIfExists()
|
||||
}
|
||||
VBMetaParser().clean("vbmeta.img")
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(MiscImgParser::class.java)
|
||||
}
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
// Copyright 2021 yuyezhong@gmail.com
|
||||
//
|
||||
// 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 bcb
|
||||
|
||||
import cfig.bcb.BootloaderMsg
|
||||
import cfig.bootimg.Common.Companion.deleleIfExists
|
||||
import org.junit.After
|
||||
import org.junit.Test
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.File
|
||||
|
||||
class BootloaderMsgTest {
|
||||
private val log = LoggerFactory.getLogger(BootloaderMsgTest::class.java)
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
File(BootloaderMsg.miscFile).deleleIfExists()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun writeRebootBootloaderTest() {
|
||||
val msg = BootloaderMsg()
|
||||
msg.clearBootloaderMessage()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun readBootloaderMsgTest() {
|
||||
val msg = BootloaderMsg()
|
||||
msg.readBootloaderMsg()
|
||||
log.info(msg.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun writeOptions() {
|
||||
val msg = BootloaderMsg()
|
||||
msg.updateBootloaderMessageInStruct(arrayOf(
|
||||
"--prompt_and_wipe_data",
|
||||
"--locale=zh_CN"))
|
||||
msg.writeBootloaderMessage()
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun rebootRecovery() {
|
||||
val msg = BootloaderMsg()
|
||||
msg.updateBootloaderMessageInStruct(arrayOf())
|
||||
msg.writeBootloaderMessage()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rebootCrash() {
|
||||
val msg = BootloaderMsg()
|
||||
msg.writeBootloaderMessage(arrayOf(
|
||||
"--prompt_and_wipe_data",
|
||||
"--reason=RescueParty",
|
||||
"--locale=en_US"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rebootOTA() {
|
||||
val msg = BootloaderMsg()
|
||||
msg.writeBootloaderMessage(arrayOf("--update_package=/cache/update.zip", "--security"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rebootWipeAb() {
|
||||
val msg = BootloaderMsg()
|
||||
msg.writeBootloaderMessage(arrayOf(
|
||||
"--wipe_ab",
|
||||
"--wipe_package_size=1024",
|
||||
"--locale=en_US"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rebootWipeData() {
|
||||
val msg = BootloaderMsg()
|
||||
msg.writeBootloaderMessage(arrayOf(
|
||||
"--wipe_data",
|
||||
"--reason=convert_fbe",
|
||||
"--locale=en_US"))
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
package bcb
|
||||
|
||||
import cfig.bcb.VirtualABMsg
|
||||
import cfig.bootimg.Common.Companion.deleleIfExists
|
||||
import cfig.helper.Helper
|
||||
import cfig.helper.Helper.Companion.check_call
|
||||
import org.apache.commons.exec.CommandLine
|
||||
import org.junit.*
|
||||
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.IOException
|
||||
|
||||
class VirtualABMsgTest {
|
||||
private val log = LoggerFactory.getLogger(VirtualABMsgTest::class.java)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
Assume.assumeTrue(
|
||||
try {
|
||||
"adb --version".check_call()
|
||||
true
|
||||
} catch (e: IOException) {
|
||||
false
|
||||
}
|
||||
)
|
||||
Assume.assumeTrue(Helper.powerRun3(CommandLine.parse("adb root"), null)[0] as Boolean)
|
||||
"adb wait-for-device".check_call()
|
||||
"adb shell dd if=/dev/block/by-name/misc of=/data/vendor/debug.misc skip=512 bs=64 count=1".check_call()
|
||||
"adb pull /data/vendor/debug.misc".check_call()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parseVAB() {
|
||||
FileInputStream("debug.misc").use {
|
||||
val vab = VirtualABMsg(it)
|
||||
log.info("VAB msg: $vab")
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
File("debug.misc").deleleIfExists()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue