[XPERIA X10 Themes and Apps] _calum_:
Modifying Services.jar

To modify services.jar we need to decompile the classes.dex file contained within. We can do this with baksmali:

1. Open services.jar (found in system/framework) with 7zip

2. Extract classes.dex from the archive

3. Open a command window and use the following to decompile:

java -jar baksmali-1.2.5.jar -o out\services classes.dex

4. You will now have a subfolder out\services with the decompiled .dex classes (smali files)

These sort of modifications will not be necessary very often. Two things that have been looked at so far are changing the text color on the status bar clock (just the clock, not the notification text) and changing the signal strength to show dBm instead of just the bars. The text color of the clock is relatively simple and is described below. The signal strength mod was done by MrRusch and requires a bit more code, he describes the process here.

I have attached a converter MrRusch has put together to convert java to smali. This is really helpful when trying to figure out how to modify the smali or event just trying to figure out what a piece of smali code does.

Since the 15th of december the sources for 2.1 are available here. Now we can see how the original java relates to the decompiled smali code.

You can find a reference for all the smali ops here. This one is more complete but I prefer the first purely because it's a bit more compact and it has most of what I need anyway. Thanks to untemensch and JesusFreke for the links.

Status Bar Clock Color:

I have since figured out how to do this without changing any code, just by changing some xml in res/layout, but I will keep this here as I think it is a nice, easy to follow example to start out with.

This section describes how to modify the color of the clock in the status bar without changing the color of the notification text (changing all of the status bar text is described in the xml section above).

First we need to have a look at the smali file com\android\server\status\StatusBarIcon.smali to see how the color of the clock text is set. I use Visual Studio to view/edit the smali files, but you can use any text editor - I have seen PSPad recommended a few times.

If we look at the init method we can see the following piece of smali code:

.line 44
.local v15, textColor:I
const/4 v13, -0x1

.line 50
.local v13, styleIndex:I
const v18, 0x1030079

:try_start_1f
sget-object v19, Lcom/android/internal/R$styleable;->TextAppearance:[I

move-object/from16 v0, p1

move/from16 v1, v18

move-object/from16 v2, v19

invoke-virtual {v0, v1, v2}, Landroid/content/Context;->obtainStyledAttributes(I[I)Landroid/content/res/TypedArray;

move-result-object v5

.line 53
.local v5, a:Landroid/content/res/TypedArray;
const/16 v18, 0x0

move-object v0, v5

move/from16 v1, v18

move/from16 v2, v16

invoke-virtual {v0, v1, v2}, Landroid/content/res/TypedArray;->getDimension(IF)F

move-result v16

.line 54
const/16 v18, 0x3

move-object v0, v5

move/from16 v1, v18

move v2, v15

invoke-virtual {v0, v1, v2}, Landroid/content/res/TypedArray;->getColor(II)I

move-result v15

Here's a run-down:

I'm pretty sure the lines that start with a '.' are comments from the decompiler.

The .line 4 entries are just a reference to the line number in java source-code. And I think the .local v15, textColor:I entry just notes the v15 variable name and type (I = integer).

The first bit of interest is the line invoke-virtual {v0, v1, v2}, Landroid/content/Context;->obtainStyledAttributes(I[I). The obtainStyledAttributes method definition can be found here. There are a few overloads, but the call is to the method that accepts an integer and an integer array as parameters - hence the (I[I), I and [I. The three variables in braces at the start denote the object that the method is being called on (the Context object) and the two parameters respectively. The first parameter (v1) is a resource ID and a few lines up the v18 variable is copied to this (move/from16 v1, v18 - this means move the value from v18 to the v1 variable). v18 was declared a few lines above again with the value 0x1030079. This ID can be found in the framework xml-file res/values/public.xml and the value is the name of a style (TextAppearance.StatusBar) that can be found in res/valus/styles.xml (see the xml section above).

The result of obtainStyledAttributes is copied to v5 (move-result-object v5) which (in .line 54) is copied to v0 which is then used to call Landroid/content/res/TypedArray;->getColor with the two integer parameters v18 (0x3) and v15 (0x100 - this is the color black). The first parameter is the index of the color in the style array (index 3 in v5) and the second is the default value (black).

The result of getColor() is then copied to v15 and reused later when setting up the text view for the clock:

.line 61
.local v14, t:Landroid/widget/TextView;
move-object v0, v14

move-object/from16 v1, p0

iput-object v0, v1, Lcom/android/server/status/StatusBarIcon;->mTextView:Landroid/widget/TextView;

.line 62
new-instance v11, Landroid/widget/LinearLayout$LayoutParams;

const/16 v18, -0x2

const/16 v19, -0x1

move-object v0, v11

move/from16 v1, v18

move/from16 v2, v19

invoke-direct {v0, v1, v2}, Landroid/widget/LinearLayout$LayoutParams;-><init>(II)V

.line 65
.local v11, layoutParams:Landroid/widget/LinearLayout$LayoutParams;
const/16 v18, 0x0

move-object v0, v14

move/from16 v1, v18

move/from16 v2, v16

invoke-virtual {v0, v1, v2}, Landroid/widget/TextView;->setTextSize(IF)V

.line 66
invoke-virtual {v14, v15}, Landroid/widget/TextView;->setTextColor(I)V

All this means that to change the color of the clock text only, we need to declare a new style and use the ID of this style in the call to obtainStyledAttributes. When adding the style to styles.xml I keep it in the same place as the other status bar styles:

...
<style name="TextAppearance.StatusBar" parent="@style/TextAppearance">
<item name="textSize">16.0sp</item>
<item name="textStyle">normal</item>
<item name="textColor">@color/semc_text_color_primary</item>
</style>
<style name="TextAppearance.StatusBar.Clock" parent="@style/TextAppearance">
<item name="textSize">16.0sp</item>
<item name="textStyle">normal</item>
<item name="textColor">@color/semc_text_color_clock</item>
</style>
...

The name of the style can be anything, what is important is the ID reference in public.xml, and that a color semc_text_color_clock is declared in colors.xml (see the xml section above).

The style reference in public.xml must have an ID that starts with 0x0103****. This is the ID range for styles, strings and other resources have a different ID range. I always add the new style at the bottom of the style group so that I can easily see which is the next free ID:

....
<public type="style" name="SEMCTheme.Dialog.Alert.Vanilla" id="0x01030139" />
<public type="style" name="TextAppearance.StatusBar.Clock" id="0x0103013a" />
....

Now that we have added a new style we just need to adjust the smali code to use it. Change the code above from:

.line 50
.local v13, styleIndex:I
const v18, 0x1030079

to:

.line 50
.local v13, styleIndex:I
const v18, [B]0x103013a[/B]

Now our new style is used for the call to obtainStyledAttributes. We then need to recompile the smali to a classes.dex file and update the services.jar:

Run the following command to recompile the smali:

java -jar smali-1.2.5.jar -o out\classes.dex out\services

The output file may be a slightly different size than the original classes.dex but as long as you don't get any errors it will be OK.

Now open services.jar with 7zip and update it with the new classes.dex (drag/drop).

Done :) Push the services.jar to your phone with adb and reboot (make sure you have updated framework-res.apk with the new xml resources first, otherwise our new ID will point to a non-existant resource)