[T-Mobile myTouch 4G Slide] Blue6IX:
Return to Contents Page - doubleshot Developers Reference

**For some reason the board merged all of my posts...sorry guys, just gonna have to deal I suppose.

Since sharing my notes here about what i've learned/am learning for Android development seems to be helping people beyond myself, i'd like to share my notes regarding Edify scripting so far.

WARNING: You can really screw up your phone once you start making your own flashable zips. While this guide gathers scripting information from all over XDA and distills it into MT4GS implementation, it is not a difinitive resource.

There are blatant gaps of knowledge in this thread. I am trying to include as many of the helpful resources I can that were found here at XDA. Links are at the bottom of this post - if you found a good edify-script reference here at XDA, please reply with a link to this thread for people researching this topic. Thanks!

I highly recommend you have a good understanding of what you are doing before you go ahead and do it. Follow the links, drift through the XDA knowledge base and soak it all in.

Feel Free to ask any questions or add anything related to Edify scripting to this thread.

Here's how this thread is laid out:

Post 01 - Contents

Post 02 - Edify Scripting Explanations.

Post 03 - Before we begin...

Post 04 - Mounting your way out of RAM.

Post 05 - Delete, Demolish and Destroy.

Post 06 - Break more stuff: Format <-- Flashable zip 'format' utility here.

Post 07 - Reserved. ( Installing )

Post 08 - Reserved. ( Permissions )

XDA Links:

Tools:

nubecoder's amend to edify script converter

Utility i've been signing my zips with by benjamminzIS

Posts/Threads:

Single post by nubecoder, syntax

Tutorial by coolexe on Amend/Edify script syntax

Thread by DooMLoRD, pieces of the mounting puzzle

...and more when I get time to track them down and put them in.

One thing to note about this thread is that it's not just a quick synopsis of syntax. There are plenty of threads like that around XDA, and they are all helpful. The MT4GS has some specifics to keep in mind, and there are some things to work around in CWM, but we can start to tackle some of this with this guide.

This thread is more of an explanative review of the process, an attempt to point out some common, or not so common mistakes that are easily made...and a bit more of a look at why things are happening beyond just how to do them.

More of a theory behind the application of principles and so not a quick read.

I would like to say thank you to computerkid23 for putting an end to trying out every update-binary I could find looking for the right one. By allowing me to re-use the one from the "Tasteless Venom" ROM, I stopped treading water and started making forward progres again.

This is the update-binary file used in all of my scripts, and has the proper syntax for the commands to work with the MT4GS.

---------- Post added at 04:54 PM ---------- Previous post was at 04:51 PM ----------

Edify Scripting Explanations

ClockworkMod Recovery 3.0+ and update-script

Read the post from the above link to understand that Amend scripting is the old way and Edify scripting is the new way.

While the commands are essentially the same, the syntax and expression is much different in Edify then Amend.

If you are trying to flash a zip, and want to figure out if it's an Amend or Edify:

Both Edify and Amend flashable zips have the following directory:

/META-INF/com/google/android/

In the android folder:

This is the easiest way for you to tell what kind of script you have - in simplest form and first point of recognition:

1 File = Amend

2 Files = Could be Edify

If two files exist in this directory, check to make sure they match the quote above for Edify. Make sure it's not a mix of an Amend update-script and Edify update-binary.

If everything matches up to Edify so far, then browse through the thread and look at the command syntax laid out for Edify. If what you're looking at doesn't match, then you'll have to seriously downgrade your CWM version to run it - meaning you will have to write your own recovery from scratch.

With that understanding, for the remainder of this thread we will only be focusing on Edify scripting.

update-binary

This is a not so trivial piece of your scripting puzzle. There are an unknown number of different update-binary files out there. They support different script syntax, make sure your updater-script and update-binary match.

---------- Post added at 04:54 PM ---------- Previous post was at 04:54 PM ----------

Before we begin...

...there are just two things we have to go over:

1 - Backups.

2 - The ui_print("") command.

First, read my Thread about backups. Specifically post 2 about making a Clockworkmod backup.

You should have multiple copies of each backup you keep, on different machines or media. If your only backup is on the sdcard of your phone, and you accidentally erase it, that's it - it's gone.

Make sure your CWM backup works before relying on it. The only thing worse then losing a backup is keeping a bad one you think is good.

Your can't just pull individual images out of it and restore it through CWM, you need the whole backup file that was generated by CWM. You can restore only specific partitions from the complete backup file if you want.

Basically, your backup is your security. Once you start writing scripts you run into the problem of being able to affect changes on things you weren't intending to and you just can't fix - you need that backup.

Second, the ui_print("") command.

Syntax:

ui_print("some message goes here");
ui_print("another one here");
ui_print("the next line is a blank line");
ui_print("");

This command simply prints whatever text is in between the quotes to the screen when the line is executed.

This includes white-space, so any spaces you make in the quotes are preserved, even if it's the first thing after the quoatation mark.

Okay - so here's one of those MT4GS tips that you find through trial and error:

- The MT4GS screen in recovery, after executing a file, fills up to a certain point with printed text.

1 - Verticle:

To get your title, introduction line, whatever, as the top line erasing all code that came before it, you must print 23 lines of text to the screen. The first line must be blank.

Example:

That's how your first 3 ui_print("") commands should be entered into your script to make your title be the top line of code on the screen when the script is finished in CWM.

2 - Horizontal:

To keep your text from being split at an awkward place, remember that you get about 40 characters on a line before it starts printing to the next line on the screen. If this happens, that second line counts as one of your 23.

I attached some screenshots of some of my scripts at the bottom of this post. They show what clockworkmod looks like as soon as the script is finished, before the user changes anything.

With the parameters of 23 lines down (first line blank) and no more then 40 characters to any individual line, you can format the final output of your script to be much more useful to the user.

If a person sees all the commands they entered leading up to executing your script, but only a few of them and some are already pushed off screen, it can be confusing.

This is a part of the development approach that is appealing to me, the end user experience and what I can do to enhance it. By making the final output of your script consist of only what you want to be shown on the screen, you have an opportunity to communicate to the user.

Make sure to check all your spelling - honestly, when I see typos in the printed output of an installation script, on any software on any platform, I start to worry about what's in the rest of the code. By presenting yourself well here, you can establish a level of trust with the end user in your product. ( Obvious slang and intentional misspellings notwithstanding )

Something else to consider is that if you don't use the progress commands to show that the script is doing something, a long operation might confuse a user into thinking their phone froze. They might then do something really bad in the worried and irrational state of mind that could put them in...

I put that up there as an extreme example, writing radios is not part of this thread ( initially... ) but imagine being that user who doesn't really know what's happening to their device, doesn't have the technical background to know what to do in a situation like that, and they might irrationally pull the battery while it really is writing the radio in a panic.

When contemplating the effects of what actions you do and do not take, always consider the worst possible thing you can think of happening as being the most likely to occur.

Simply using a progress bar, or as I prefer, the ui_print(""); command to keep something happening on the screen keeps the user from guessing. If enough space is left over, you can even tell them what they have to do next.

Or you could just chalk it up to me being too particular about the details...

Anyways, check out these screenshots to see how you can use the space available to you to direct the user and possibly eliminate some confusion:

---------- Post added at 04:55 PM ---------- Previous post was at 04:54 PM ----------

Mounting your way out of RAM

-Mount Points

-"mount" command

-"unmount" command

The most feature-rich script for reprogramming your Android device just the way you want loses all value if all you are doing is writing to RAM.

If you do everything else right, but don't mount your partitions correctly, then your script will either error out or just zip through the install in no time flat.

First piece of information you need to know-

doubleshot mount points:

/dev/block/mmcblk0p22 /system ext4
/dev/block/mmcblk0p23 /data ext4
/dev/block/mmcblk0p24 /cache ext4

These are the mount points for system, data, and cache.

Thanks to nubecoder for the how to on finding them out Here:

You do not need root to generate this info from Terminal Emulator.

Part 1 - Mount point usage:

mount("ext4", "EMMC", "/dev/block/mmcblk0p22", "/system");

** I have had mixed results using update-binary files that called for 3 parameters to mount. I may not know enough to explain why, but my theory is that:

-"EMMC" parameter allows me to force the action to take place not in RAM, can someone verify this?

Ever since using this method of mounting I haven't suffered the problem of the script running itself out in RAM and not doing anything.

By executing the above line of code, you will mount the system partition of the internal phone memory. Partitions must not be mounted if the format command is executed. For all other actions, mounting is the first step.

Part 2 - unmount when finished.

unmount("/system");

unmounts the partition and makes it safe to format.

If you are done with it for the time being in your script, you can unmount and remount it later when you need it.

All mounted partitions should be unmounted before the script is done.

Part 3 - Example

Dummy code in green, mount & unmount in bold

[COLOR="Green"]Lines(of code);
in_your(script);[/COLOR]

[B]mount("ext4", "EMMC", "/dev/block/mmcblk0p22", "/system");[/B]

[COLOR="Green"]More(code);
the(stuff you do);
to_the(system partition);[/COLOR]

[B]unmount("/system");[/B]

[COLOR="Green"]possibly_even(more code);
to(do more things);
after_you(are done with);
the(system partition);[/COLOR]

So here we learned how to mount, unmount, and some reasons why we need to do or not do this.

I am a big fan of unmounting a partition when I am done using it, and you'll see examples of this throughout my scripts as they surface here at XDA. I know some people will disagree with me about this, but here's my reasoning:

-The only way to change something on a partition is to mount it first, so if a partition is not mounted nothing is happening to it.

*Format is the exception. A partition must not be mounted if you want to format it. See the post on format below to find out more.

By not mounting a partition if I don't need to, or unmounting a partition when you aren't using it for a time, you can prevent accidents and put another layer of protection on the execution of your code.

As much as you should mold to the way the machine works, it is here to serve you and that's gotta give both ways. At some point the code has to be decipherable to a human, and there's no harm in spreading things out a little bit to also make sure everything happens in it's proper way at the right time.

---------- Post added at 04:55 PM ---------- Previous post was at 04:55 PM ----------

Delete, Demolish and Destroy

-delete

-delete_recursive

Warning: Delete means exactly that - gone. There is no un-delete, there is only a backup. If you don't have a backup, you just lost whatever you deleted.

Please read my guide on backups before playing with this.

Delete Files:

Single Item:
delete("/path/to/file.extension");

Multiple Items:
delete("/path/to/file01.extension","/path/to/file02.extension","/path/to/file03.extension");

Pretty simple with the delete commands. In the Stock App Reference i've listed the direct edify delete commands for every stock app, so I won't get back into it like that here.

We will pull an example, though, the annoyingly broken stock calculator:

Okay, so what we see here is this app has an .apk file at the location /system/app/Calculator.apk

In order to delete that, we need to put this line in our script:

delete("/system/app/Calculator.apk");

But wait! There's more. HTC includes a .odex file with most of the stock software on this device. The weirdly broken, poorly coded calculator is no exception, and we can delete that one too:

delete("/system/app/Calculator.odex");

Of course, that would turn into a huge script, if you had to type in the whole command every time you wanted to delete a file. To that end, we can group multiple targets to one action like this:

delete("/system/app/Calculator.apk","/system/app/Calculator.odex");

Which matches what I quoted from the guide.

Again, be sensible about this. You could group a large amount of apps into a single delete command, but then you're going to have to browse one line of code that goes on forever when you check it or have to change/fix it.

I'd recommend grouping a handful together, then just running another delete command with another group of apps if you have to do a whole lot of them. It makes it easier for you to figure out what's going on, and troubleshoot the script if necessary.

What's the point of fitting 100+ apps on one line of code, if it takes you 10 times as long to check it? Being too efficient to be productive, break it up a little bit.

delete is one of the most powerful commands at your disposal. It takes a lot of work to make something, but one stray delete command to wreck it all. Use with caution.

Delete Directories:

Single Item:
delete_recursive("/path/to/directory");

Multiple Items:
delete_recursive("/path/to/directory01","/path/to/directory02","/path/to/directory03");

If you thought delete was a powerful command, then delete_recursive just upped the bar.

Instead of being restricted to just single files, you can now nuke a whole folder. It also deletes everything in the folder, in case that didn't click yet.

Be even more careful in using this command, because doing somethine like delete_recursive("/system/customize/resource") to get rid of all the stock wallpapers and browser bookmark pictures you don't want sounds like a great idea...until you realize that folder also has your boot animations, default ringtones, and other things that you probably want to have.

( But that's okay, you made a backup first, right? )

To continue our calculator example from above, we might want to also delete the data file from the app. If you're going to get rid of something, you should try to get rid of all of it's pieces to prevent problems on the system.

delete_recursive("/data/data/com.android.calculator2");

That line of code deletes the data directory for the stock calculator, so now we can go ahead and replace it with something working right.

If we were going to be replacing just the calculator, or only one or two things here and there, then this method is acceptable.

If you can manage resetting all the permissions correctly, you can go ahead and delete a directory you have a copy of, and then just install it back there later in the script minus the stuff you didn't want. This is a hazardous road to take, but if you're deleting 37 out of 43 files in a folder, and you have to call them all by name...

( I have had mixed results with this, nothing that makes me eager to take this road if I can avoid it )

I'd like to get more into delete_recursive, but it's actually better addressed in the next post, so skip ahead to format.

---------- Post added at 04:56 PM ---------- Previous post was at 04:55 PM ----------

Format:

Well, here we are. The big fish of the "break stuff" commands. Often times, though, it's like using an axe when you need a hobby knife.

Unfortunately, the format commands seem to be broken for us at best, not usable at worst. If someone can put more time into it then i've been able to to figure out why or if there is a way to get them to work, then please don't hesitate to post here.

Meantime, while I was browsing XDA seeking answers, I stumbled across This Post and just started laughing and walked away from the computer for a little while.

And while that wasn't the answer I was looking for, I made the decision to drop it for now and just move on with the fix.

Here's the workaround:

delete_recursive("/cache")

Simply delete the directory.

Thanks Firon!

Now, here's where we get back to the part about mounting and unmounting the same partition multiple times in a single script. Follow along with this progression:

This block of code clears the cache:

mount("ext4", "EMMC", "/dev/block/mmcblk0p24", "/cache");
delete_recursive("/cache");
unmount("/cache");

...and this block of code clears all user data:

mount("ext4", "EMMC", "/dev/block/mmcblk0p23", "/data");
delete_recursive("/data");
unmount("/data");

And they are both self-contained. As long as neither is mounted before entering these 3 lines of code each, what you get here is Mount, Wipe, Unmount - done.

The reason why I picked /cache and /data to use as an example, is because when you put them both together like this:

mount("ext4", "EMMC", "/dev/block/mmcblk0p24", "/cache");
delete_recursive("/cache");
unmount("/cache");
mount("ext4", "EMMC", "/dev/block/mmcblk0p23", "/data");
delete_recursive("/data");
unmount("/data");

...you've just essentially called for a factory reset in your script. The next time the operating system boots, it will rebuild the cache and data partitions from whatever is installed on the device.

Remember, though, rebuilding the data partition will make it take noticeably longer to boot, and you should let it sit for a few minutes after it finishes booting.

The reason why people get choppy installs and errors from custom ROMs sometimes, is because as soon as the screen gets past the boot screens, they just start playing with it right away. What they don't realize is that the data partition is pretty complex, and a lot of that stuff is still being created, sorted and saved behind the scenes.

When you start making the device do stuff, before it's done what it's already doing, it tries to serve you first. It will clear parts of the data partition that are still being built from memory to do what you just told it to do.

Because of that, as you use it over time you run into the missing or corrupted files/directories/permissions/etc... because what was in memory was lost before it got saved on first boot.

Letting it sit for 5 minutes after first boot from a factory reset or any simulation thereof is vital to a smooth and proper install. Developers, the average user will not know this and getting the word out with your install will save you troubleshooting phantom problems users report to you that can't be duplicated by anyone else.

Now that we've gone through all that, here are two flashable zip files already signed and ready to use:

1 - Blue6IX_A01_Wipe.zip

- This will simply delete recursively /cache /data and /system.

Users: Flash this zip before installing a custom ROM or a CWM backup to eliminate 'bleed through' from the previous ROM/Install.

WARNING: If you do not have a /system partition waiting to install after flashing this zip, you will have a phone without Android on it. Check the ROM or CWM backup BEFORE flashing this zip to make sure you will have software on your phone when you are done. If this message scares you, then use the next listed flashable zip instead.

Developers: The three blocks of code that perform the wipes of these partitions should be the beginning of your installation script, if you are providing all the resources you need for your installation INCLUDING a pre-populated /system partition.

If you are not providing the /system partition in it's entirety, then see the next script:

2 - Blue6IX_B01_Wipe.zip

- This deletes recursively only /cache and /data.

Users: Flash this zip to simulate a factory reset. Your data partition will be rebuilt on the next boot by what's installed on the device. This does not delete any system programs, but any apps installed through any market or user data of any kind ( contacts, notes and etcetera... ) will be lost.

This flashable zip is just like doing a factory reset from the settings menu, except it's from recovery.

Developers: If you are just modifying the stock /system partition, then the code in this script that isn't ui_print("") should be at the beginning of your install script.

If part of your install instructions include "do a factory reset" or "format /data and /cache" then just insert this code as the first thing your installer does and you can take that hassle out of their hands.

Since we have people of all levels of experience and ability flashing ROMs, we should try to take as many extra steps out of their hands as possible - it's just easier for everyone around.

This will ensure that no random data gets left over from the old environment before you changed it. It ensures that your information gets written correctly - as long as you play nice with the pre-existing /system partition.

So notes on these scripts:

1 - A01 CAN LEAVE YOU WITH NO ANDROID SOFTWARE ON YOUR PHONE IF YOU HAVE NO /system PARTITION TO INSTALL BEHIND IT!!

* - On the user level, I run flashable.zip before I restore a clockworkmod backup. This cleans out those 3 partitions and lets the backup write to fresh memory space.

* - On an advanced user level, I usually just install the system.img file from the CWM backup and let it build the cache and data on the next boot. Seems cleaner to me that way.

- I wrote all the text in that prints to the screen to give it a cleaner, less confusing look. When the script is done, the interface is much less busy from random notices and not as intimidating to casual users.

+ - Neither of these flashable zips has anything to do with boot or recovery images or partitions. It's all cache, data and/or system.

( I don't know what would happen if you powered off without a /system partition. I'd think that it would be able to get to the recovery utility ( Clockworkmod ) where you could flash a /system partition, CWM backup or ROM. )

(( I'm not brave enough to find out on my phone, because while i'm 90% sure it would be fine, i'm not willing to try without more research first - Don't hold me responsible if you wipe /system and then power off and something bad happens...So make sure you have a new /system partition ready to install if you use Wipe A01 ))

And, last warning. If you don't know what you're doing with these flashable zips, then don't use them. Ask a question here first, i'll be happy to answer as best as I can.