[AT&T Samsung Galaxy S II Skyrocket SGH-I727] car vs driver:
Using the Aroma 2.56 installer.​

Purpose:

In this tutorial I'll cover how to setup and configure the Aroma installer for installing a ROM. This is a basic how-to guide and covers the basic functionality and concepts of the installer itself. I've provided a link to an article from Dblfstr that goes into great detail around EDIFY and Aroma. After you read this tutorial, go read his.

This tutorial assumes you are doing this in Linux.

Keep in mind, I'm probably not the best person to write a tutorial. I'm more of a hands on person, so let me know if I missed anything significant.

Links:

Very in depth tutorial on Aroma and EDIFY: http://xdaforums.com/showthread.php?p=28706056

Get Latest Version of Aroma Here: http://xdaforums.com/showthread.php?t=1461712

Tutorial Sections:

1. Downloading the Aroma package and looking at whats there (initial setup).

2. Updating the installation menu (aroma-config).

3. Updating your installer-script (EDIFY).

4. Putting all the files in your ZIP package.

5. Testing your installation.

[ Section 1: Downloading the Aroma Package ]

Ok, so this is pretty straight forward. Get Latest Version Here: http://xdaforums.com/showthread.php?t=1461712

Save that into the same directory as your ROM zip file, I'd recommend creating a new directory for both so we have a clean place to work. With that being said, create that new directory, lets call it: ~/distrib

For the rest of this tutorial, I will expect that you created the distrib directory and that we will be working from there. So, put your ROM zip and the Aroma zip in that directory and lets get started.

Extract the aroma zip into the distrib directory. You'll notice that it will create a directory structure that looks like:

~/distrib/META-INF/com/google/android/aroma

The android and aroma directories are where we will focus our effort for the tutorial. Notice that the above mirrors the directory structure in your zip (with the addition of the aroma directory).

[ INITIAL SETUP ]

Now that we have the package, we need to make some immediate changes to it. This is the step that people usually screw up or skip entirely, but its very simple.

1. In the android directory, delete the file called update-binary-installer

2. Take the update-binary from your ROM zip, rename it to update-binary-installer and put it in the same directory

We do this because you need to have the Aroma update-binary fire when the zip is flashed, this is the binary that controls aroma. Your binary, now called update-binary-installer will be triggered by aroma to perform the actuall installation. If you don't do this, either aroma won't run or it'll blow up as soon as it tries to run the install (post Aroma menus).

Go reread those steps again, make sure you do it correctly. You cannot use the update-binary-installer from the Aroma package, it is not intended for the skyrocket and bad things will happen. When we push the package into your zip, your original update-binary script will be overwritten by the Aroma one in the next step ...

Next, lets go ahead and push some files into your ROM zip.

1. Open up your ROM zip with archive manager and navigate to: /META-INF/com/google/android/

2. Grab the aroma directory from where we unzipped it and drop it in the android folder in your zip.

3. Now, drop in the update-binary and update-binary-installer files that we updated earlier.

Note that we have not yet pushed the updater-script and aroma-config files into the zip yet. That's because there are LOTS of changes that you have to make to these files before pushing them in.

Lastly, to finish the initial setup we do in fact need the updater-script from your ROM zip. We are now working in the ~/distrib/META-INF/com/google/android directory on your computer.

1. Rename the installer-script to installer-script-aroma (don't delete it, it is a good reference file).

2. Extract the updater-script from your ROM and put it in the same directory (~/distrib/META-INF/com/google/android)

At this point, your ROM will not flash at all. We have to fix that by creating your installation menu and then interpreting all of the selected options in the updater-script.

[ Section 2: Updating the installation menu. ]

Open up the aroma-config file from ~/distrib/META-INF/com/google/android

This is where all the menu magic happens. In this section I'll briefly show you what to update, but I'm not going to create a gigantic step by step for each section. There are other threads on xda that you can read for that.

[ BASIC CHANGES ]

First, you need to update some of the basic stuff such as the name of your rom, developer, date, etc ..

Here is a sample from my ROM installation, obviously you'll need to change the values appropriately:

ini_set("force_colorspace", "rgba");

ini_set("rom_name", "CvD-Nibbles");

ini_set("rom_version", "1.3-S");

ini_set("rom_author", "car vs driver @ xda");

ini_set("rom_device", "Galaxy Skyrocket");

ini_set("rom_date", "28 Nov 2012");

Next, you can update the SHOW ROM INFORMATION section if you want to change the layout, here's what I did:

viewbox(

#-- Title

"<~welcome.title>",

#-- Text

"<~welcome.text1>...\n\n"+

#-- Get Config Value

" ROM\t\t: <b><#selectbg_g>"+ini_get("rom_name")+

"</#></b>\n"+

" VERSION\t: <b><#selectbg_g>"+ini_get("rom_version")+

"</#></b>\n"+

" DEVICE\t\t: <b><#selectbg_g>"+ini_get("rom_device")+"</#></b>\n\n",

#-- Icon

"@welcome"

);

Moving on to the license agreement. In stock form Aroma includes the Apache license agreement, you'll likely want to put in your own. The license file is located in the aroma directory and is called license.txt

The changelog secion is probably already commented out in the stock file, you can use it if you like. Just make sure to format the changelog file properly.

[ MENU SELECTIONS ]

What you'll notice is that the menu sections fire sequentially. In the aroma-config whatever order you have each section from top to bottom is the order they will be presented to your users. You have unlimited flexibility to swap the order around, and even force the user back to other sections if they have made conflicting selections (I won't get into this, but you should be able to figure it out if you look through the file).

Next you need to build all of the secions that dictate what the user can choose from. You'll want to make sure you order these secions in a logical manner:

1. Type of installation (custom, basic, etc)

2. Kernel selection (if appropriate)

3. Primary application installation choices

3. Secondary application installation choices (something like allowing which google apps to be installed if you want to break them up)

4. Teritary application installation choices (as necessary)

5. Theme choices

6. Any additional tweaks or bloatware .. whatever you like.

One of the things that you need to have planned out in advance is which apps are optional and how you want to group them in the installation menus. That will dictate how many different sections you have.

The reason why you include the installation type first is becayse you can use the chosen value from that menu to drive which of the following menus are shown to the user. If they choose a standard installation, you may elect not to provide any additional choices, or you may elect to provide some of them, but not all. That's your choice.

Below is the installation type code in Nibbles, I use this answer to drive the subsequent menus available to the user:

menubox(
#-- Title
"Nibbler Menu",

#-- Sub Title
"Please select an option below",

#-- Icon
"@apps",

#-- Will be saved in /tmp/aroma/main.prop
"main.prop",

#-------------------------+-----------------[ Menubox Items ]-------------------------+---------------#
# TITLE | SUBTITLE | Item Icons #
#-------------------------+-----------------------------------------------------------+---------------#

"Base Installation", "Base Installation With Pre-Selected Applications", "@install", #-- selected = 1
"Custom Installation", "Choose your apps, launcher, etc.", "@install", #-- selected = 2
"Apps Only",	"Choose only apps to install (NO ROM)", "@install", #-- selected = 3
"System Info", "Get and show device/partition information", "@info" #-- selected = 4
);

I'm not going to break down in detail what all of the different pieces are. You should be able to figure this out simply by looking at it.

In the Nibbles installation, all of the subsequent sections check the value of main.prop to determine which ones to skip and which ones to show. The section on which options the user has to wipe their device is only shown when they have elected to install the ROM itself. The below statement is what checks that:

if prop("main.prop","selected") == "1" || prop("main.prop","selected") == "2" then

[ MENU OPTION TYPES ]

Now you have to decide which menu lists will allow only 1 choice to be made and which ones will allow multiple selections. I'll explain this simply by showing you the difference in code. You should be able to extrapolate the differences simply by reading the below ...

Single option only:

"CM Trebuchet Launcher",	"",	1, #-- selected.0 = 1
"Apex Launcher",	"", 0, #-- selected.0 = 2
"Nova Launcher", "", 0, #-- selected.0 = 3
"Android 4.2 Launcher", "", 0 #-- selected.0 = 4

Allow multiple choices:

"Apps", "", 2, #-- Group 1
"Accuweather", "Accuweather App and Widget", 0, #---- item.1.1
"Adobe Flash", "Adobe Flash Player (this cannot be installed from market)", 0, #---- item.1.2
"Apollo", "Apollo Music Player", 0, #---- item.1.3
"Browser", "Stock Jellybean Web Browser", 0, #---- item.1.4

Notice that the key difference here is using the selected keyword or the item keyword. If you use selected, that means the user can only choose one of the options. Using the item keyword means that users can select many options.

While using selected, it is critical to set one of them as pre-selected. In my example, CM Trebuchet Launcher has a value of 1 - meaning that it is selected.

While using item, you don't have to select any of them because the user can simply de-select it. The assumption here is that nothing in this list is required.

This is probably the part of the tutorial that I should spend the most time explaining. But I'm lazy. Read the code, you're a dev, you can figure it out.

One important thing to remember, each section needs a unique .prop file. You define what that file is here:

#-- Will be saved in /tmp/aroma/apps.prop
"apps.prop",

All you need to do for each section is change the file name. Leave the .prop extension on it.

I recommend reading through the next sections of the file to understand what they do and decide if you need to make any adjustments. I won't cover that in detail because everyone will like do it differently. You can also leave it as is.

[ Section 3: Updating your installer-script (EDIFY). ]

Your installer-script is where the magic happens. The stock installer-script that is created when you build your ROM is very basic. It just drops in system files, sets up busybox and runs some permissioning.

When using aroma, you will keep the main pieces of the stock script and then add in all of your optional pieces. All you are going to do here is add in a bunch of conditional statements that read the prop file values and determine what gets installed. To read a value from a prop file is simple:

if file_getprop("/tmp/aroma/main.prop","selected") == "1" then

Just choose which prop file you want to interrogate, and which parameter value. After that, install the appropriate package the user has selected. Below is a compound interrogation example from Nibbles. Basically, I only allow for the user to choose which status bar config if they have chosen the custom installation.

if file_getprop("/tmp/aroma/main.prop","selected") == "2" then
ui_print(" Configuring Status Bar Options");
if file_getprop("/tmp/aroma/options.prop","selected.0") == "1" then
package_extract_file("resources/ClockAndIcons/NibblesStock/SystemUI.apk","/system/app/SystemUI.apk");
endif;
if file_getprop("/tmp/aroma/options.prop","selected.0") == "2" then
package_extract_file("resources/ClockAndIcons/NibblesCenter/SystemUI.apk","/system/app/SystemUI.apk");
endif;
if file_getprop("/tmp/aroma/options.prop","selected.0") == "3" then
package_extract_file("resources/ClockAndIcons/CM10Stock/SystemUI.apk","/system/app/SystemUI.apk");
endif;
if file_getprop("/tmp/aroma/options.prop","selected.0") == "4" then
package_extract_file("resources/ClockAndIcons/CM10Center/SystemUI.apk","/system/app/SystemUI.apk");
endif;
endif;

You'll see that the first if statement checks which installation type they have chosen. The next set of statements figures out which of the clock options the user selected and installs the appropriate one.

This is perhaps the most complicated part of setting up your installation. So, I won't spend any more time explaining it to you :) There are far too many variables related to how you want your installation to go. I've attached my installer-script from Nibbles v1.3-S to lead you by example here. If you get stuck, just ask questions.

[ Section 4: Putting all the files in your ZIP package. ]

From the section above, you'll see that I have a directory in my zip named /resources. You can package your zip any way you like, just don't much around with the /system directory AT ALL. Create a new directory in the root of your zip where you will put all the optional components. Seperate them logically so it is easier for you to manage. Feel free to download the Nibbles ROM and see how I structured the optional components as an example.

The critical components of aroma have been added to the zip already per my earlier instructions. Now you need to drop in your edited aroma-config and updater-script files to the android directory - overwrite any that may already be there.

One other thing to note, if you are making some system apps optional, you'll need to take them out of the system directory and put them in your new resources directory. This is because the system installation would add them even if the user didn't want them. Again, look at Nibbles as an example.

[ Section 5: Testing your installation. ]

The best way to test is to just flash the damn thing. Seriously. Aroma has a nice log feature that logs the installation (assuming you made it that far) so you can figure out what you broke. But, here's my standard testing procedures...

1. Flash the zip.

2. If aroma starts, you're in good shape. If it doesn't, it is likely because you have improperly formatted some code in aroma-config. Keep in mind, the installation has not validated or executed the updater-script yet.

3. Carefully go through each section in Aroma. Check for spelling errors, make sure the sections load in the correct order, make sure the options you elected to add are all there as well.

4. Made it through all the sections? Good ...

5. Right when you land on the instalation confirmation page, you need to grab a few files off the phone. So make sure it is plugged in via USB and you have ADB.

6. Grab the .prop files with ADB. They are located in /tmp/aroma on the device. What we are checking here is that the appropriate value has been assigned to each option based on your selection in the menu itself. If those look good and line up with your selections, let the installation run.

7. At this point, Aroma hands over control to the updater-script and update-binary-installer.

8. Any bugs you have from this point forward will likely be in the updater-script.

9. When it fails, because it will the first time, I promise you ... save the log file.

10. Once the log is saved, do NOT reboot the phone yet.

11. Grab the log file off the device with ADB to see what part broke.

12. Fix it and try again.

Once you've had a clean installation, the next thing to do (other than saving and pulling your log file) is to reboot and make sure it all works.

You'll spend just as much time testing and fixing bugs as you did building the installation itself. But, once you get past all the common mistakes, your next use of Aroma will go far smoother.

Good luck!

EDIT:

Remove the following line from aroma-config if you are planning to kang mine. It will cause the installer to hang at launch.

ini_set("force_colorspace", "rgba");