Merge "Add batch generation to OTAGUI." am: 2e1cfae4fd
Original change: https://android-review.googlesource.com/c/platform/development/+/1775726 Change-Id: I230b943a2c54de6b052ee0de26ed73238ef7533f
This commit is contained in:
96
tools/otagui/src/components/BatchOTAOptions.vue
Normal file
96
tools/otagui/src/components/BatchOTAOptions.vue
Normal file
@@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<form @submit.prevent="sendForm">
|
||||
<FileList
|
||||
v-model="incrementalSources"
|
||||
:disabled="!otaConfig.isIncremental"
|
||||
label="Source files"
|
||||
/>
|
||||
<v-divider />
|
||||
<FileList
|
||||
v-model="targetBuilds"
|
||||
label="Target files"
|
||||
/>
|
||||
<v-divider />
|
||||
<OTAOptions
|
||||
:targetDetails="targetDetails"
|
||||
:targetBuilds="targetBuilds"
|
||||
@update:otaConfig="otaConfig=$event"
|
||||
/>
|
||||
<v-divider class="my-5" />
|
||||
<v-btn
|
||||
block
|
||||
type="submit"
|
||||
>
|
||||
Submit
|
||||
</v-btn>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import OTAOptions from '@/components/OTAOptions.vue'
|
||||
import FileList from '@/components/FileList.vue'
|
||||
import { OTAConfiguration } from '@/services/JobSubmission.js'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
OTAOptions,
|
||||
FileList,
|
||||
},
|
||||
props: {
|
||||
targetDetails: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
incrementalSources: [],
|
||||
targetBuilds: [],
|
||||
otaConfig: new OTAConfiguration(),
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
checkIncremental() {
|
||||
return this.otaConfig.isIncremental
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
checkIncremental: {
|
||||
handler: function () {
|
||||
this.$emit('update:isIncremental', this.checkIncremental)
|
||||
},
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$emit('update:isIncremental', this.checkIncremental)
|
||||
this.$emit('update:handler', this.addIncrementalSources, this.addTargetBuilds)
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* Send the configuration to the backend.
|
||||
*/
|
||||
async sendForm() {
|
||||
try {
|
||||
let response_messages = await this.otaConfig.sendForms(
|
||||
this.targetBuilds, this.incrementalSources)
|
||||
alert(response_messages.join('\n'))
|
||||
this.otaConfig.reset()
|
||||
} catch (err) {
|
||||
alert(
|
||||
'Job cannot be started properly for the following reasons: ' + err
|
||||
)
|
||||
}
|
||||
},
|
||||
addIncrementalSources (build) {
|
||||
if (!this.incrementalSources.includes(build)) {
|
||||
this.incrementalSources.push(build)
|
||||
}
|
||||
},
|
||||
addTargetBuilds (build) {
|
||||
if (!this.targetBuilds.includes(build)) {
|
||||
this.targetBuilds.push(build)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
73
tools/otagui/src/components/FileList.vue
Normal file
73
tools/otagui/src/components/FileList.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<h4> {{ label }} </h4>
|
||||
<select
|
||||
class="list-box"
|
||||
:size="modelValue.length + 1"
|
||||
v-bind="$attrs"
|
||||
@click="selected=$event.target.value"
|
||||
>
|
||||
<option
|
||||
v-for="build in modelValue"
|
||||
:key="build"
|
||||
:selected="build === selected"
|
||||
>
|
||||
{{ build }}
|
||||
</option>
|
||||
</select>
|
||||
<v-btn
|
||||
class="my-2"
|
||||
:disabled="!selected"
|
||||
@click="deleteSelected"
|
||||
>
|
||||
Remove selected item
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
modelValue: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selected: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
deleteSelected() {
|
||||
let deleteIndex = this.modelValue.indexOf(this.selected)
|
||||
if (deleteIndex > 0) {
|
||||
this.$emit(
|
||||
"update:modelValue",
|
||||
this.modelValue
|
||||
.slice(0, deleteIndex)
|
||||
.concat(
|
||||
this.modelValue.slice(
|
||||
deleteIndex+1,
|
||||
this.modelValue.length
|
||||
))
|
||||
)
|
||||
} else {
|
||||
this.$emit(
|
||||
"update:modelValue",
|
||||
this.modelValue.slice(1, this.modelValue.length)
|
||||
)
|
||||
}
|
||||
this.selected = null
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.list-box {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -28,6 +28,37 @@ export class OTAConfiguration {
|
||||
this.extra = ''
|
||||
}
|
||||
|
||||
/**
|
||||
* Take in multiple paths of target and incremental builds and generate
|
||||
* OTA packages between them. If there are n incremental sources and m target
|
||||
* builds, there will be n x m OTA packages in total. If there is 0
|
||||
* incremental package, full OTA will be generated.
|
||||
* @param {Array<String>} targetBuilds
|
||||
* @param {Array<String>} incrementalSources
|
||||
* @return Array<String>
|
||||
*/
|
||||
async sendForms(targetBuilds, incrementalSources = []) {
|
||||
const responses = []
|
||||
if (!this.isIncremental) {
|
||||
responses.push(
|
||||
... await Promise.all(
|
||||
targetBuilds.map(async (target) => await this.sendForm(target))
|
||||
)
|
||||
)
|
||||
} else {
|
||||
for (const incremental of incrementalSources) {
|
||||
responses.push(
|
||||
... await Promise.all(
|
||||
targetBuilds.map(
|
||||
async (target) => await this.sendForm(target, incremental)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
return responses
|
||||
}
|
||||
|
||||
/**
|
||||
* Start an OTA package generation from target build to incremental source.
|
||||
* Throw an error if not succeed, otherwise will return the message from
|
||||
@@ -36,14 +67,16 @@ export class OTAConfiguration {
|
||||
* @param {String} incrementalSource
|
||||
* @return String
|
||||
*/
|
||||
async sendForm(targetBuild, incrementalSource='') {
|
||||
async sendForm(targetBuild, incrementalSource = '') {
|
||||
let jsonOptions = Object.assign({}, this)
|
||||
jsonOptions.target = targetBuild
|
||||
jsonOptions.incremental = incrementalSource
|
||||
jsonOptions.id = uuid.v1()
|
||||
for (let flag of OTAExtraFlags) {
|
||||
if (jsonOptions[flag.key]) {
|
||||
jsonOptions.extra_keys.push(flag.key)
|
||||
if (jsonOptions.extra_keys.indexOf(flag.key) === -1) {
|
||||
jsonOptions.extra_keys.push(flag.key)
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
|
||||
@@ -41,11 +41,13 @@
|
||||
|
||||
<script>
|
||||
import SingleOTAOptions from '@/components/SingleOTAOptions.vue'
|
||||
import BatchOTAOptions from '@/components/BatchOTAOptions.vue'
|
||||
import BuildLibrary from '@/components/BuildLibrary.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SingleOTAOptions,
|
||||
BatchOTAOptions,
|
||||
BuildLibrary,
|
||||
},
|
||||
data() {
|
||||
@@ -56,6 +58,7 @@ export default {
|
||||
refresh: false,
|
||||
tabs: [
|
||||
{label: 'Single OTA', component: 'SingleOTAOptions'},
|
||||
{label: 'Batch OTA', component: 'BatchOTAOptions'}
|
||||
],
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user