Contribute to the Easy Installer
/e/OS easy-installer Build documentation
Tools required to build
The team member who developed the easy-installer used
- Netbeans 11.3 (/!\ netbeans 11.0 doesn’t work properly with javaFX)
- Gradle 4.10
- OpenJFX11+: doc
- Java JDK 11+
How to clone the project
Run this command in a terminal
git clone https://gitlab.e.foundation/e/tools/easy-installer.git
How to build
Open a terminal at the root of the project
prompt: ./gradlew dist
Note: “dist” for “distribution”
Result
It will create 3 zipped artifacts, zipped together in a single archive :
- linux-x64
- windows-x64
- mac
Location of the artifacts :
Zipped build : “/build/distributions/”
Unzipped build : “/build/image/”
What does this command do?
Compiled java version is provided from “buildSrc” folder. There is one version for each platform (windows, osx, linux). That will allow to have an installation free application. thanks to java 9+, it only includes required modules.
99% of the job is done by the “badass jlink plugin” (see section below). The remaining 1% consist of:
- copying ADB
- copying heimdall
- copying fastboot
- flash’s scripts
from “buildSrc” and “flash-scripts” folders into the build.
What is used to make the build ?
It uses the “badass jlink plugin”
Feature idea
- Add support for a new device
- You need to own the device
- First step is to create configuration files for the Easy Installer
- If necessary, create the missing scripts to be able to achieve the installation
- make
./gradlew dist
to create a build for one platform at a time depending on a param. i.e:./gradlew dist windows
or./gradlew dist linux
How to support or add a new device ?
The easy-installer uses two configuration files for each device.
note: We are using herolte (Samsung galaxy S7) as an example here
The config files are located in “src/main/resources/yaml/” folder.
src
--main
----java
----resources
------css
------fonts
------fxml
------images
------instructions
------lang
------yaml
--------**herolte.yml**
--------**herolte_fs.yml**
1. First file: .yml
The first file “herolte.yml” defines the flashing process. The file is a YAML resource.
Structures and nodes of the file
name: herolte
flash:
f1:
script: wait-download
parameters:
heimdall_folder_path: ${HEIMDALL_FOLDER_PATH}
codes:
ok:
0: ~
ko:
1: script_error_waitDownload_1
output: ~
succeed: f2
failed: ~
f2:
script: oem-unlock
parameters:
heimdall_folder_path: ${HEIMDALL_FOLDER_PATH}
codes:
ok:
0: ~
ko:
10: script_error_oemUnlock_10
output: ~
succeed: f3
failed: ~
...
-
Name
defines the codename of the device. This value is a simple String. example:herolte
for S7,hero2lte
for S7 edge,dreamlte
for S8, … -
f1
is the step key (it identifies the step). The value is the step defined by following elements: script
contains the name of the flash-script to call. There is no extension because it is defined at runtime (this allows to use either “.sh” for linux and mac or “.bat” for windows)-
parameters
contains a map of parameters to use when the script is called. The order should be the one expected by the script. There are two types of values for a parameter:- a fixed parameter which is a raw string.
example:
my_key: foobar
- a changing parameter which is defined at runtime. Then its value must be the key - in uppercase - wrapped in ‘{‘ and starts with ‘$’.
example:
my_key: ${MY_KEY}
- a fixed parameter which is a raw string.
example:
-
codes
contains two sub lists:ok
corresponds to script’s exit when the step succeeds, andko
corresponds to script’s exit when there is an error. The codes returned by the script are always numeric value. Theko
codes can be defined with an error message which will be displayed to the user if it happened.example:
10: script_error_oemUnlock_10
.The error message is a key corresponding to a value in the translations file (
src/main/resources/lang/traduction.properties
) -
output
can be used to define a variable than must be read from the last line of the running script. example:output: ${MY_KEY}
corresponds to a step where the installer should read the last line provided by the script and store it in a java variable “MY_KEY” which would be used in a later step. The value of output is always structured like a changing parameter. -
succeed
specifies the next step’s code after a success. failed:
defines the next step’s code to call after a failure.
Special step:
f7:
script: askAccount
parameters: ~
codes: ~
output: ~
succeed: f8
failed: ~
This is the only step which is empty. There is no script “askAccount”. It is used by easy-intaller to know when to show the UI which lets the user request an invitation email to create an account. Please always add this step before the last step.
2. Second files: _fs.yml
This second file specifies extra data (which aren’t optional)
Structures and nodes of the file
sources:
rom:
url: https://images.ecloud.global/stable/herolte/e-latest-herolte.zip
filePath: e-latest-herolte.zip
twrp:
url: https://images.ecloud.global/stable/twrp/herolte/twrp-3.2.3-0-herolte.img
filePath: twrp-3.2.3-0-herolte.img
flash:
f1:
ui:
type: action
title: stepTitle1On7
instruction:
- install_instr_turnOff
- install_instr_startDownload
- install_instr_acceptWarning
stepNumber: 1/7
titleIcon: Download.png
instructionImg: group2.png
f2:
ui:
type: load
title: stepTitle2On7
instruction:
- install_instr_oemUnlock
stepNumber: 2/7
averageTime: 8
...
It contains two parts: sources
which specifies files that need to be downloaded and flash
which defines UI for the different steps.
sources
Each different files that needs to be downloaded should be specified here.
Use a key to identify it :
example: rom
, twrp
, vendor
, patch
, …
url
specifies the url that points to the resource. example:url: https://path/to/the/file.extension
-filePath
specifies the file’s name on the user’s computer once it has been downloaded
/!\ files must have a sha256sum to check integrity. The sha256 should be the exact filename(with extension) +”.sha256sum”. The sha256sum should be in the same folder as the target file. It will be automaticaly downloaded.
flash
Uses the exact same key as in the first file. They must be identical.
ui
contains an element which defines what is displayed during the step.
There are three types of UI (user interface): action
, load
and askAccount
action
type
It corresponds to the step where the user has to perform an action (like pressing button).
It has the following structure:
type: action
title: stepTitle1On7
instruction:
- install_instr_turnOff
- install_instr_startDownload
- install_instr_acceptWarning
stepNumber: 1/7
titleIcon: Download.png
instructionImg: group2.png
-
title
contains the translations’ key for the step’s title. The value is defined insrc/main/resources/lang/traduction.properties
-
instruction
are translations’ keys for the instruction at this step. Their values are defined insrc/main/resources/lang/traduction.properties
It is also used to identify pictures to display along with the instruction. Pictures are defined like instructions’ text but are locatd insrc/main/resources/instructions/imageName.properties
-
stepNumber
defines the step place in the process -
titleIcon
is displayed left to the title value -
instructionImg
is ignored and will be removed soon.
load
type
type: load
title: stepTitle2On7
instruction:
- install_instr_oemUnlock
stepNumber: 2/7
averageTime: 8
-
title
is the same as foraction type
-
instruction
is the same as foraction
type except that it must have only one instruction. -
stepNumber
is the same as foraction
type. -
averageTime
defines the averageTime the step is required to do its job. it is in second.
askAccount
type
It’s a special type, which only contains type: askAccount
.
Its step key (f
Good practice:
- ’~’: is used for empty or null value.
- defines “normal” step code with ‘f’ and a incremental number. It helps to understand the whole process.
- defines “failure” step code with ‘e’ and a incremental number. It helps to understand the whole process.
Lets make the translation file
What is the translation file?
A translation file has extension “.properties”.
It also contains country code & local lang code before the extension and is separated by "_"
.
Base name is: translation.
The complete name is:
translation.properties
for the default translation’s file. This file will be used when no translations are found in a specific language.translation_xx_XX.properties
It is a language specific translation’s file. i.e :translation_fr_FR.properties
.
It is stored in the project and build with the App.
To update translation, we need to rebuild the application.
Contents of the translation file
The content of a translation file is not limited in size.
_one row = one translation
a Row is structured with the following pattern: reference=value
reference
is the code used to load the value.value
is the raw text that will be display to the user
example: trad_1_title=first title of the translation
note: if you add a space between the =
and the first character of your translation, the displayed message will include this space too.
But you can add a space between the reference and the =
without any problem.
a. Line break
In most case, you should let the application decide to break line or not.
If you really need a line break, use \n
.
example: trad-example=firstline\nsecondline
Result:
firstline
secondline
How to choose reference
for a translation
In order to have easy to maintain translation’s file,
We’ll define reference
following a defined pattern.
Each part of the pattern will be separated by "_"
-
First part is an identifier for the UI which use the button.
-
Second part is an element type identifier. Is it a simple label ? a title ? a button ?
-
third part is a unique identifier
Theorical examples:
UI-1_label_uid1
UI-2_button_uid1
UI-2_button_uid2
UI-2_title_uid1
a. UI identifier
The different interface are listed below (inspired by the tab’s name in this document :
- welcome
- before
- connect
- devMode
- ADBdebug
- detect
- download
- install
- eAccount
- congrats
- feedback
note: we don’t use UI
with a number corresponding at the order of the interface in the whole process.
Because if we want to change the process order, we’ll have to change all translation reference…
b. Element type
possible element’s type with corresponding code to use, are:
- Main title :
mTitle
- title:
title
- subtitle :
sbTitle
- Label :
lbl
- Button :
btn
- instruction:
instr
c. Unique identifier
use ‘uid’ with a simple incremental value.
The incremental value restart from 0 for each UI’s identifier and each element type.
or use a text identifier.
or no unique identifier if this is the only one element of this type
d. Real example
note: in the following example, the value describe the position or the content, but it can be anything else.
interface_mTitle_uid1=This is a main title
interface_sbTitle_uid1=this is the first subtitle
interface_sbTitle_uid2=this is the second subtitle
interface_sbTitle_uid3=this is the third subtitle
interface_lbl_version=this is the version Number
interface_lbl_uid1=this is the label below the first subtitle
interface_lbl_uid2=this is the label below the second subtitle
interface_lbl_uid3=this is the label below the third subtitle
interface_btn_uid1=this is the button to change interface