快速调试安卓Framework源码三(通过修改smali实现)
-----------------------------------------------------------
(1)把要调试的 jar 包取出来。
比如我们要调试 frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.java, 这个文件编译后在 services.jar 中。 【S 版本上这个方法还不行】
我们把 services.jar 从手机中取出来,命令如下:
adb pull /system/framework/services.jar
(2)反编译 services.jar,得到 smali 文件。
此处,我们使用 apktool 反编译 services.jar,命令如下:
$ apktool d services.jar
得到 services.jar.out/ 目录,目录下有文件如下:
$ ls -l services.jar.out/``总用量 ``20``-rw-r--r-- ``1` `mi mi ``943` `6``月 ``3` `16``:``24` `apktool.yml``drwxr-xr-x ``3` `mi mi ``4096` `6``月 ``3` `16``:``24` `original``drwxr-xr-x ``4` `mi mi ``4096` `6``月 ``3` `16``:``24` `smali``drwxr-xr-x ``5` `mi mi ``4096` `6``月 ``3` `16``:``24` `smali_classes2``drwxr-xr-x ``3` `mi mi ``4096` `6``月 ``3` `16``:``24` `unknown
(3)按照自己需求修改 smali。
3.1 使用 find 命令查找 DisplayPowerState.java 对应的 smali 文件。
services.jar.out$ find -name DisplayPowerState*``./smali/com/android/server/display/DisplayPowerState.smali``./smali/com/android/server/display/DisplayPowerState$``3``.smali``./smali/com/android/server/display/DisplayPowerState$``2``.smali``./smali/com/android/server/display/DisplayPowerState$PhotonicModulator.smali``./smali/com/android/server/display/DisplayPowerState$``1``.smali``./smali/com/android/server/display/DisplayPowerState$``4``.smali
3.2 修改 smali 文件。
我们在 DisplayPowerState.java 代码中,
151` `public` `void` `setScreenBrightness(``float` `brightness) {``152` `if` `(mScreenBrightness != brightness) {``153` `if` `(DEBUG) {``154` `Slog.d(TAG, ``"setScreenBrightness: brightness="` `+ brightness);``155` `}``156``157` `mScreenBrightness = brightness;``158` `if` `(mScreenState != Display.STATE_OFF) {``159` `mScreenReady = ``false``;``160` `scheduleScreenUpdate();``161` `}``162` `}``163` `}
要把 153 行的 if(DEBUG) 去掉,并在 154 行打印 brightness 的同时打印出来 mScreenBrightness。
我们想要修改后的样子如 154 行。
151` `public` `void` `setScreenBrightness(``float` `brightness) {``152` `if` `(mScreenBrightness != brightness) {``153` `154` `Slog.d(TAG, ``"MIUI debug, setScreenBrightness: brightness="` `+ brightness + ``" mBrightness="` `+ mScreenBrightness);``155` `156``157` `mScreenBrightness = brightness;``158` `if` `(mScreenState != Display.STATE_OFF) {``159` `mScreenReady = ``false``;``160` `scheduleScreenUpdate();``161` `}``162` `}``163` `}
在 ./smali/com/android/server/display/DisplayPowerState.smali 中找到 153 行和 154 行代码的地方:
原来的 smali
.line ``153``sget-``boolean` `v0, Lcom/android/server/display/DisplayPowerState;->DEBUG:Z` `if``-eqz v0, :cond_0` `.line ``154``new``-instance v0, Ljava/lang/StringBuilder;` `invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V` `const``-string/jumbo v1, ``"setScreenBrightness: brightness="` `invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;` `invoke-virtual {v0, p1}, Ljava/lang/StringBuilder;->append(F)Ljava/lang/StringBuilder;` `invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;` `move-result-object v0` `const``-string v1, ``"DisplayPowerState"` `invoke-``static` `{v1, v0}, Landroid/util/Slog;->d(Ljava/lang/String;Ljava/lang/String;)I
修改后的 smali如下:(我们需求主要修改去掉 if 判断,打印 brightness 的同时,并打印出来 mBrightness。)
.line ``153``new``-instance v0, Ljava/lang/StringBuilder;` `invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V` `const``-string/jumbo v1, ``"MIUI debug, setScreenBrightness: brightness="` `invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;` `move-result-object v0` `invoke-virtual {v0, p1}, Ljava/lang/StringBuilder;->append(F)Ljava/lang/StringBuilder;` `move-result-object v0` `const``-string/jumbo v1, ``" mBrightness="` `invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;` `move-result-object v0` `iget v1, p0, Lcom/android/server/display/DisplayPowerState;->mScreenBrightness:F` `invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(F)Ljava/lang/StringBuilder;` `move-result-object v0` `invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;` `move-result-object v0` `const``-string v1, ``"DisplayPowerState"` `invoke-``static` `{v1, v0}, Landroid/util/Slog;->d(Ljava/lang/String;Ljava/lang/String;)I
(4)编译 smali 得到 dex
新建目录和包名一致,com/android/server/display/,把 DisplayPowerState.java 相关的 6 个类放入其中。
com/android/server/display/``├── DisplayPowerState$``1``.smali``├── DisplayPowerState$``2``.smali``├── DisplayPowerState$``3``.smali``├── DisplayPowerState$``4``.smali``├── DisplayPowerState$PhotonicModulator.smali``└── DisplayPowerState.smali
把准备好的文件编译得到 dex 文件。
$ java -jar smali-``2.5``.``2``.jar a -o hello.dex com/android/server/display/
现在我们得到了 hello.dex,hello.dex 文件中已经包含我们修改过的代码了。
(5)push dex 到手机
$adb push hello.dex /system/framework/
(6)修改 init.rc 生效。
从手机中把 init.environ.rc pull 下来,进行修改。
$ adb pull init.environ.rc
添加 hello.dex 文件目录

再把它 push 到手机中。注意目录不一样了。
$ adb push init.environ.rc /system/etc/init
重启手机生效。
(7)验证
重启手机后,拖动通知栏的背光进度条。
使用下面命令查看日志
$adb shell logcat | grep setScreenBrightness
可以看到,如我们期望打印出来了日志。

参考: