[Android Software/Hacking General [Developers Only]] hansip87:
Hi Guys, have you ever loved the stock launcher (like i did with SE stock launcher ;) ) but wishes that it would auto rotate on your keyboard-less phone and you don't want any extra launcher? Have you ever popped out to your home launcher (after running an app) and finding the layout is rotated but soon to be set as portrait, and you want that landscape mode? Well you can actually :)

This is the requirement:

Home.apk of your phone

AutoAPKTool or APKMultiTool to decompile and recompile

Google SDK

Any editing and searching program (e.g. Notepad++ and WinGrep)

The steps are:

Backup your Home.apk

Decompile and Find the HomeActivity.smali

Change the Orientation Flag

Compile back and apply to the phone

The following sample is taken from my Modified Home.apk in Sony Ericsson, but should be comparable to all Launcher :)

These are the steps:

1. Backup your Home.apk

This is to prevent some unwanted behaviour since a home.apk is essentially your gateway to all apps so please make sure to backup (and create flashable zip to make it easier to revert back)

2. Decompile and Find the HomeActivity.smali

The idea is to find the Main Activity Class of Home Launcher (Activity is, in easier language, is the display of the active app on the screen)

Decompile the Home.apk first and find the Home Activity class.

In my sample from SE ICS Beta ROM, the file that needs to be edited is named smali\com\sonyericsson\home\HomeActivity.smali

3. Change Orientation Flag

If you have found it on the previous page, open it and find any line that contains this function

iget v6, p0, Lcom/sonyericsson/home/HomeActivity;->mDefaultOrientation:I

invoke-virtual {p0, v6}, Lcom/sonyericsson/home/HomeActivity;->[B]setRequestedOrientation(I)V[/B]

The Bold line is the essential function that determine your preferred orientation of home.apk.

After you found it, you must find the variable that used as the default orientation. From my sample above, it can be read as

[I]//this, in smali code, is p0[/I]
[B]
v6 = this.mDefaultOrientation;
this.setRequestedOrientation(v6);
[/B]

So the variable used here is the v6, which is stored before as this.mDefaultOrientation. Now your task is to find out what variable name that is used to store your Orientation Flag, and then later you need to watch for it if that variable get changed in the line.

My sample code is like this:

.method public constructor <init>()V
.
.
const v0, 0x5

iput v0, p0, Lcom/sonyericsson/home/HomeActivity;->mDefaultOrientation:I
.
.
.end method

.method public onCreate(Landroid/os/Bundle;)V
const v13, 0x4
.
.
const v10, 0x5

iput v10, p0, Lcom/sonyericsson/home/HomeActivity;->mDefaultOrientation:I
.
.

:goto_1
iget v6, p0, Lcom/sonyericsson/home/HomeActivity;->mDefaultOrientation:I

invoke-virtual {p0, v6}, Lcom/sonyericsson/home/HomeActivity;->setRequestedOrientation(I)V
.
.
.local v5, uiModeManager:Landroid/app/UiModeManager;
invoke-virtual {v5}, Landroid/app/UiModeManager;->getCurrentModeType()I

move-result v6

if-ne v6, v7, :cond_b

.line 580
const v6, 0x5

iput v6, p0, Lcom/sonyericsson/home/HomeActivity;->mDefaultOrientation:I

goto/16 :goto_1

.line 582
:cond_b
iput v13, p0, Lcom/sonyericsson/home/HomeActivity;->mDefaultOrientation:I

goto/16 :goto_1
.
.
.end method

As you see:

1. the init and OnCreate function assigns the default value to mDefaultOrientation of the Object and evaluates it if you have a docking function on the phone (:cond_b above).

2. The flag used above is set at 0x5 value, which is value of ActivityInfo.SCREEN_ORIENTATION_NOSENSOR (No sensor data will be applied to change orientation of the phone). To modify it, we need to modify that value to ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED which means it will follow device autoRotate settings.

3. In Sony Ericsson where there are docking accessories, they implement them as 0x4 (ActivityInfo.SCREEN_ORIENTATION_SENSOR) which means the device will always change the home orientation even though we turn off auto Rotate.

So, based on that info i changed the above lines to the following

.method public constructor <init>()V
.
.
[B]const v0, -0x1[/B]

iput v0, p0, Lcom/sonyericsson/home/HomeActivity;->mDefaultOrientation:I
.
.
.end method

.method public onCreate(Landroid/os/Bundle;)V
const v13, 0x4
.
.
[B]const v10, -0x1[/B]

iput v10, p0, Lcom/sonyericsson/home/HomeActivity;->mDefaultOrientation:I
.
.

:goto_1
iget v6, p0, Lcom/sonyericsson/home/HomeActivity;->mDefaultOrientation:I

invoke-virtual {p0, v6}, Lcom/sonyericsson/home/HomeActivity;->setRequestedOrientation(I)V
.
.
.local v5, uiModeManager:Landroid/app/UiModeManager;
invoke-virtual {v5}, Landroid/app/UiModeManager;->getCurrentModeType()I

move-result v6

if-ne v6, v7, :cond_b

.line 580
[B]const v6, -0x1[/B]

iput v6, p0, Lcom/sonyericsson/home/HomeActivity;->mDefaultOrientation:I

goto/16 :goto_1

.line 582
:cond_b //I keep this line to have 0x4 flag since it doesn't have to be taken care of.
iput v13, p0, Lcom/sonyericsson/home/HomeActivity;->mDefaultOrientation:I

goto/16 :goto_1
.
.
.end method

4. Compile back and Apply

Compile the Home.apk and don't forget to put the original MANIFEST Folder from original Home.apk so the Home.apk is signed :)

Voila, my Home Launcher is auto rotated now :cool:

CAUTION: Some error may occur at the first time you apply this mod (Possibly because of some unfit widgets on home when auto rotated). If it gives you error, please flash the stock one you backed up before and the home will be reset and then reapply the modded home. It should work

For further references, You can go to:

http://developer.android.com/reference/android/content/pm/ActivityInfo.html - For any kind of Orientation flag info

http://xdaforums.com/showthread.php?t=1511730 - How-to of decompile and recompile APK (especially ICS)

Any question, please feel free to ask :)

G'day!