[Android Software Development] Lens_flare:
Stage 2

Recently I had an Acer Liquid MT[now bricked], which is Qualcomm S2 device(msm7x30) and my guide defines also assume you have device with Qualcomm inside. But some of guide moments[first stage is not exception] are common for most devices with other chips.

I also used Cyanogen Mod 9 as base, so some of these defines wouldn't be applicable to your porting using AOSP base.

That was on ICS, and I will count that in while describing for those who don't care about miui version and porting something before MIUI 2.8.10.

Now I have MIUI-supported Xperia Arc S. But its MIUI is based on stock rom (such a shame). So as FXP provides us CM 10, I started to port over it to bring latest and greatest of MIUI jellybean on that device. So again Qualcomm, but with stock ICS, which means lesser quirks on porting. I again will assume you are on Qualcomm but I have to say that all defines of this stage are nomore device-specific.

Returning to guide:

Stage 2. Framework mods to make it boot

Rom not booting? - that is most likely a framework issue, that is remained from Nexus S/Galaxy Nexus. But don't run to base to grab all framework and paste it to base, else you will have a base rom instead of miui :p

My suggestion is port.

For those who are new in apktool disassembling, I suggest to read something like that http://xdaforums.com/showthread.php?t=1511730 or that http://xdaforums.com/showthread.php?t=1752201 or google it to understand common principles of work.

For framework-res.apk mods we will use Connor-apktool and scripts for ease of use: http://code.google.com/p/android-apktool/downloads/list (choose only dependencies for your platform, don't replace AAPT from them). Always choose latest one!

Let's assume again:

disassemble something - usually means issuing

apktool d [[COLOR="YellowGreen"]full name of apk or jar[/COLOR]]

command on file I specify if more info not specified

assemble something - usually means issuing

apktool b [[COLOR="YellowGreen"]disassembled apk or jar folder without .apk in name or with ".out" at the end for jars[/COLOR] ]

command on file I specify

better way to assemble is drag assembled classes.dex(or resources.arsc and xmls at rest folders in case of assembling framework-res.apk) from [file you modified]/build/apk to original file, opened as archive (in windows you also have to check out a compression rate to make it the same as there were before dragging, which prompts to you as compression method like "Normal" and "Store")

smali - piece of code on dalvik bytecode language, are part of nearly any disassembled file

smali tree/just "tree"/"*.smali" - usually means set of files with the same name in the beginning but with different end(usually with $ before), for example

RIL*.smali means:
[LIST]
[*]RIL.smali
[*]RIL$1.smali
[*]RIL$RILReceiver.smali
[*]RIL$RILSender.smali
[/LIST]

Let's start with framework mods:

All frameworks are located at system/framework.

framework.jar

Mostly issues are produced there.

Disassemble framework.jar from MIUI port you are working so you will see framework.jar.out. Go to smali folder in it. Later all actions we will produce from there (except assembling).

First replace some files from your base framework.jar (fist disassemble base rom's framework.jar and move all files I will specify, replace if asked).

Listing all smali I had to replace in framework.jar:

ICS-only:

[B]android/os/Power.smali[/B]
org/codeaurora/Performance.smali
[B]android/media/MediaRecorder*.smali[/B]
android/graphics/Paint.smali
android/os/Environment.smali
android/view/HardwareCanvas.smali
[B]android/net/wifi/WifiNative.smali[/B]

Common:

android/view/Gles20*.smali (not only canvas but all with gles20 at the beginning)
[B]android/hardware/Camera*.smali[/B]
[B]android/server/BluetoothA2dpService*.smali[/B]
[B]android/content/res/PackageRedirectionMap*.smali[/B]
[B]com/android/internal/telephony/RIL*.smali[/B]

JellyBean Only:

[B]android/bluetooth/HeadsetBase*.smali[/B]
[B]com/android/internal/app/ActivityTrigger.smali[/B]
[B]android/webkit/HTML5*.smali[/B]
[B]android/webkit/SelectActionModeCallback[/B]

I highlighted those could be common for all chips, not only for Qualcomm ones.

But some of smalis are not following common rules.

The weirdest exception of that - WebviewCore. If you replace only WebViewCore tree, Gmail, Facebook, Browser, HTML viewer and all that is using this class WON'T WORK. What was my solution is to replace Webview*.smali tree, so I met all dependencies that class may work with.

ICS-only:

That class, and Sound Recorder are in need of one property from SystemProperties.smali, which is located at android/os/.

But don't run to base to take it and replace immediately as you read :D It have to be patched

end of ICS-only

I highlighted it as ICS-only as you will just replace it on JellyBean - it's now hard to patch, but easy to replace.

>>Common Remark about patching smalis

Patching (usually named diffing, diff, that means "find differences and eliminate them") in our context is a process of comparing two files and adding contents of one of them to another and not replacing anything. Our diff process will consist of base->miui content addition so smali we modify could live in dual life - for your base and for MIUI remained framework. For start of diff you should have both base and miui files you want to modify, and a diff tool (in windows - beyond compare,total commander, winmerge or notepad++), my preference - Meld diff viewer[really simple and visual-oriented], the only thing - it's running on linux environment and I don't know if there is a windows version. Then just open files in tool and start adding. Sometimes you have to add all entries are not present in miui one from base, sometimes you should be smart enough to mod only part which needed and nothing more and also sometimes to replace pieces of code which are actually safe to do so. That's a whole process.

>>

Example - our SystemProperties.smali:

Actually after opening you see it is full of differences from base:

http://minus.com/mbmfprmG4K/

you see those green blocks? Each of them signs a missing part of code you should add, in Meld it's just about of clicking little arrow that represents that block. As for windows tools, they should have something like "add all" and many other things could do it in a batch way.

A little piece of smartness:

that file is the only one I discovered which allow replacing .line with big code pieces, see that:

http://minus.com/mdnAholnL/

do you see ".line 126" and HUGE code block against it? you may forget about ".line 126" and copy block against it with no doubt. Note that line numbers etc could change, always check before doing something.

That line also became a dealbreaker on JellyBean, that's why we decided it would be better to just replace it. Ecample will give you a clue just about common patch process.

>>

Another file has to be modified in same way - AssetManager.smali, which is located at android/content/res.

Beware of replacing anything on it[only add, as stand before], if something went wrong, it might produce awful logcat nobody could understand so you have to re-port rom again to catch a causer.

Another interesting patch you should perform if you have different than RIL telephony class.

To determine which ril class you have, seek for following line in your build.prop:

ro.telephony.ril_class=

If you don't have such, mostly it means you are using RIL class and don't need a patch.

in my case it was:

ro.telephony.ril_class=LGEQualcommRIL

so I'll describe a process for it, pointing what is common.

All ril classes located at com/android/internal/telephony, so go to it.

LGEqualcommRIL have a single smali, so copy only that one[if your class also have another smali with the same name, for example LGEStarRIL$1.smali, copy them too], Also, unlike most classes in CM, LGEQualcommRIL have a dependency - QualcommSharedRIL, which tree you should also move to that folder near LGE one.

Classes that are also have that dependency:

LGEQualcommUiccRIL

HTCQualcommRIL

SamsungQualcommUiccRIL

Others are dervied from RIL and don't have any dependencies like that. As CM involves more and more devices, to determine what dependencies you actually need, ask source code:

public class LGEQualcommRIL extends QualcommSharedRIL implements CommandsInterface

extends means your dependency you have to also add to MIUI, if it is "RIL", go ahead and continue porting.

To make your class work instead of RIL, you should modify MIUI' PhoneFactory.smali located at the same folder in following way:

.line 136
new-instance v8, Lcom/android/internal/telephony/RIL;

invoke-direct {v8, p0, v4, v0}, Lcom/android/internal/telephony/RIL;-><init>(Landroid/content/Context;II)V

->

.line 136
new-instance v8, Lcom/android/internal/telephony/[B]LGEQualcomm[/B]RIL;

invoke-direct {v8, p0, v4, v0}, Lcom/android/internal/telephony/[B]LGEQualcomm[/B]RIL;-><init>(Landroid/content/Context;II)V

it changes a constructor of RIL class to LGEQualcommRIL class. If my lines incorrect, just type RIL in search in Phonefactory, it will show you exactly 2 defines with "RIL" involved.

Another case for patching is android/media/AudioFormat.smali.

Copy all missing lines from base to miui, it would be enough. I have decide to not replacing it coz of constructor that is differ and might one day turn into bomb.

The most complicated smali case, WebSettingsClassic. It do contains lines that should be added, also lines that should be slightly modified.

Let's try to make the process bit easier with these steps:

first of all, find those fields:

.field private mMediaPreloadEnabled
.field private mWebGLEnabled:Z

they are at the beginning of file, marked as green blocks. Attention: then there is a listing that asks you about default value, like that:

.line 91
iput-boolean v2, p0, Landroid/webkit/WebSettingsClassic;->mMediaPreloadEnabled:Z

DON'T EVEN TOUCH THEM! Even if you know what are you doing - it will fail on boot if you placed that lines in miui file.

interesting place here.. when you will search for webgl from the beginning, you will hit such block, marked as blue (incompatible):

goto/16 :goto_1
.end method

.method private native nativeIsWebGLAvailable()Z
.end method

while miui file will show just that:

goto :goto_1

and ".end method" after. "You f***n kiddng?" - will you ask.. yeah, pure cheat. Let's fix it up:

paste only:

.end method

.method private native nativeIsWebGLAvailable()Z

before ".end_method" but after "goto :goto_1", so that full block will be instantly turned to whie:

goto :goto_1
.end method

.method private native nativeIsWebGLAvailable()Z
.end method

except "goto", which will show as differ, but who cares? :D

After searching "webgl" on base file you will possibly see a code block starting with:

.method public declared-synchronized isWebGLAvailable()Z

add it without any thought. You should do the same with following methods:

.method public declared-synchronized setMediaPreloadEnabled(Z)V
.method public declared-synchronized setWebGLEnabled(Z)V

btw, those methods are so-called "setters" - methods in class that intended to adjust value to class field.

DON'T ADD ANYTHING ELSE, IT WILL POSSIBLY BREAK BOOTING AGAIN! You've been warned.

Framework.jar port done!

the only thing to do - assemble it.

services.jar

Unlike framework.jar, there are lesser things to do. But they are also significant for porting process.

ICS-only:

InputManager*.smali - the only thing should be replaced [and located in com/android/server/wm/].

On JellyBean it is located at com/android/server/Input ands also have to be replaced.

You may also replace usb folder, but actually those who have MTP(devices with kernel 3.0 or so, that are having new "USB gadget framework" drivers, consult with development branch for details) are in no need to do so, as for others (as of mine instance on MT development) you have to replace it. In stage 4 I will present my ways to make usb subsystem work on miui.

Also, there is a new smali on Jellybean: watchdog*.smali. Just replace whole tree of this in com/android/server/.

As for diff files, there is one: PowerManagerService.smali(may I shorten its name to PMS?)

there is no matter to diff it like others as it have too much dependencies to resolve and may cause your system crash.

ICS-only:

So, it only asks about nativeStartSurfaceFlingerOffAnimation method. but hey, PMS do have such method, but its name is nativeStartSurfaceFlingerAnimation, so without "Off"; my solution is to add "Off" to it, see that stack:

http://minus.com/lY4DiQfJ451Aq

that's where you should find you first entry (there are 2)

second entry showed there:

http://minus.com/lchMVcHtKe46T

after editing , you should see a huge block to add:

http://minus.com/lbmNygeJBs9klv

add it, and that smali is ported.

end of ICS-only

On jellybean porting it more trivial:

nativeCPUBoost is missing. You will have some defines in base file. Use search by keyword "cpuboost" in base file to determine where they are and just add them to miui one.

defines will be:

.method private static native nativeCpuBoost(I)V

-method definition.

.method public cpuBoost(I)V

-method code block.

and nothing extra.

Assemble new services.jar.out to services.jar when complete.

Done those but still not boots or boots but functions improperly? see next Stages- 3 and 4, I will enlighten all moments of debugging what's wrong and also additional tweaks for specific devices that faced problems with porting [It's just impossible to do that for each device, so there is a great thread you could always ask what's wrong if my advices didn't help].