2011年2月17日木曜日

Motorola Milestone2のBatteryLevelを1%Stepにしてみた


Milestone2に限らずMotorolaのAndroid端末のBatteryLevelは10%Stepでしか表示できず、3の倍数と3がつくバッテリー値でアホになるアプリの作者とか涙目な仕様でした…

でも実は内部的には1%Stepな値も持っており(Debug用のようですが)xdaのMotorola Defyスレには1%StepでBatteryLevelを表示するアプリが出てきました。

DefyBatt & DefyLivepaper - Battery Widget & Livewallpaper for Defy scaling in 1% Step

値を確認するだけならこのアプリをインストールすればOKなのですがやっぱ普段使ってるアプリも1%Step表示にしたいよねぇ…つー事でごにょごにょする事にしました。


どーやって1%Stepの値拾ってくるの?ってのはこのスレ見れば分かると思います…
[Q] How to write "capacity" without stopping Update?


capacityの値ではなくcharge_counterの値を拾ってくればOKという事ですね。

Motorola端末は色々と制限があるのでちょっと回りくどい方法になってしまっています…
書き換え対象はおなじみのservices.jarになります。

/smali/com/android/server/BatteryService.smali

iget v3, p0, Lcom/android/server/BatteryService;->mBatteryLevel:I

invoke-virtual {v1, v2, v3}, Landroid/content/Intent;->putExtra(Ljava/lang/String;I)Landroid/content/Intent;

BatteryLevelをBroadCast Intentで投げてる箇所がみつかりました…ここで投げてる値をcharge_counterの値に差し替えます。

#iget v3, p0, Lcom/android/server/BatteryService;->mBatteryLevel:I
invoke-direct {p0}, Lcom/android/server/BatteryService;->getBatteryLevel1Step()V
iget v3, p0, Lcom/android/server/BatteryService;->mBatteryLevel1Step:I
invoke-virtual {v1, v2, v3}, Landroid/content/Intent;->putExtra(Ljava/lang/String;I)Landroid/content/Intent;


getBatteryLevel1Stepをsmaliで1から書くのは面倒臭いので適当なアプリを作りそいつをbaksmaliしたものを流用します…javaのコードはこんな感じ

private void getBatteryLevel1Step(){


FileReader reader = null;
try{
reader = new FileReader("/sys/class/power_supply/battery/charge_counter");
}catch(IOException e){}
try{
char[] buf = new char[20];
int read = reader.read(buf);
reader.close();
String batteryLevelsysfs = new String(buf, 0, read);
batteryLevelsysfs = batteryLevelsysfs.replace("\n", "");
int mBatteryLevel1Step = Integer.parseInt(batteryLevelsysfs);
if(mBatteryLevel1Step >= 100){
mBatteryLevel1Step = 100;
}

System.out.println(mBatteryLevel1Step);


}catch(Exception e){

}

}

でbaksmaliし、ちょっと書き換えたのがこれ・・・BatteryService.smaliに追加します。

.method private getBatteryLevel1Step()V
.locals 8

.prologue
.line 30
const/4 v4, 0x0

.line 32
.local v4, reader:Ljava/io/FileReader;
:try_start_0
new-instance v5, Ljava/io/FileReader;

const-string v6, "/sys/class/power_supply/battery/charge_counter"

invoke-direct {v5, v6}, Ljava/io/FileReader;-><init>(Ljava/lang/String;)V
:try_end_0
.catch Ljava/io/IOException; {:try_start_0 .. :try_end_0} :catch_1

.end local v4 #reader:Ljava/io/FileReader;
.local v5, reader:Ljava/io/FileReader;
move-object v4, v5

.line 35
.end local v5 #reader:Ljava/io/FileReader;
.restart local v4 #reader:Ljava/io/FileReader;
:goto_0
const/16 v6, 0x14

:try_start_1
new-array v1, v6, [C

.line 36
.local v1, buf:[C
invoke-virtual {v4, v1}, Ljava/io/FileReader;->read([C)I

move-result v3

.line 37
.local v3, read:I
invoke-virtual {v4}, Ljava/io/FileReader;->close()V

.line 38
new-instance v0, Ljava/lang/String;

const/4 v6, 0x0

invoke-direct {v0, v1, v6, v3}, Ljava/lang/String;-><init>([CII)V

.line 39
.local v0, batteryLevelsysfs:Ljava/lang/String;
const-string v6, "\n"

const-string v7, ""

invoke-virtual {v0, v6, v7}, Ljava/lang/String;->replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;

move-result-object v0

.line 40
invoke-static {v0}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I

move-result v2

.line 41
.local v2, mBatteryLevel1Step:I
const/16 v6, 0x64

if-lt v2, v6, :cond_0

.line 42
const/16 v2, 0x64

.line 45
:cond_0
#sget-object v6, Ljava/lang/System;->out:Ljava/io/PrintStream;

#invoke-virtual {v6, v2}, Ljava/io/PrintStream;->println(I)V
iput v2, p0, Lcom/android/server/BatteryService;->mBatteryLevel1Step:I
:try_end_1
.catch Ljava/lang/Exception; {:try_start_1 .. :try_end_1} :catch_0

.line 52
.end local v0 #batteryLevelsysfs:Ljava/lang/String;
.end local v1 #buf:[C
.end local v2 #mBatteryLevel1Step:I
.end local v3 #read:I
:goto_1
return-void

.line 48
:catch_0
move-exception v6

goto :goto_1

.line 33
:catch_1
move-exception v6

goto :goto_0
.end method



箱用意しなくてはいけないので追加

# instance fields
.field private mBatteryLevel1Step:I


書き換え終わったらコンパイルして/system/frameworkにつっこめばOK…


java?なにそれ美味しいの?な人なのですごい適当です、ゴメンナサイ

2011年2月12日土曜日

Milestone2 framework-res.apk edits

Milestone2のブラジル版FW、MILA2_U6_3.12.0のキャリア情報表示の所が変な感じだったのでframeworkを書き換えた。


status_bar_expanded.xml

<TextView android:textAppearance="?textAppearanceLarge" android:textColor="?textColorSecondaryInverse" android:layout_gravity="center_vertical" android:id="@id/spnLabel" android:paddingLeft="4.0dip" android:layout_width="wrap_content" android:layout_height="0dip" />

<TextView android:textAppearance="?textAppearanceLarge" android:textColor="?textColorSecondaryInverse" android:layout_gravity="center_vertical" android:id="@id/cbLabel" android:paddingLeft="4.0dip" android:layout_width="wrap_content" android:layout_height="0dip" />


UK版FWは@id/plmnLabel、@id/spnLabelの二つのみ表示なのだがブラジル版はさらに@id/cbLabelも表示されてる。
@id/plmnLabelだけあれば十分なので他二つをandroid:layout_height="0dip"とし、表示されないようにした。

2011年2月6日日曜日

Motorola Milestone2 Customize



Milestone2は普段こんな感じで使ってます…

Build.prop edits

ro.sf.lcd_density=210
windowsmgr.max_events_per_sec=60
dalvik.vm.heapsize=48m

VM Heapsizeは32MB位でも良いかもしれませんが…


Overclock/Memory thresholds
Overclock

echo 57 > /proc/overclock/max_vsel
echo 1200000 > /proc/overclock/max_rate

Memory thresholds

echo "1536,2048,4096,15360,17920,20480" > /sys/module/lowmemorykiller/parameters/minfree


/system/etc/init.dにスクリプトを入れ、OS起動時に反映されるようにしている。
init.dのスクリプトを起動させる方法は/system/etcにinstall-recovery.shというファイルを作成し、

#!/system/bin/sh
busybox run-parts /system/etc/init.d

とするだけ…


Auto Brightness fix
Milestone2のAuto Brightnessがうまく動いてくれないのでTaskerというタスクを自動化アプリを使いfixする事にした。
シェルスクリプトを実行させたいのでLocale Execute Plug-inも入れておく。

Tasker
Locale Execute Plug-in

ActionのトリガーにLight Levelを指定


ActionにLocale Execute Plug-inを選択しスクリプトに

@! echo 2 > /sys/class/leds/lcd-backlight/brightness


あとはLightLevel幾つでBrightnessを幾つに設定するか微調整していく。
私はLightLevel0~40%でBrightness2、41~60%で50、それ以上で240の3段階にしている。

そこそこ値段の高い有料アプリで使い方を解説している日本のサイトが殆どありませんがカスタマイズ好きにはたまらないアプリではないでしょうか…結構敷居は高いですが。

---
Firmware:MILS2_U6_2.3.4
SIM:docomo音声

/system/appはStockのまま、deodexもしていない。
docomoデータSIMを入れているとバッテリー消費が激しいのでデータ通信はHW-01C経由

BatteryLifeはUnplugから11時間、Display点灯2時間45分でBattery残り 49%てな感じ…平日真面目にお仕事してる日なら予備バッテリー無くてもなんとかなるレベル(予備バッテリー4本持ち歩いてますが。)