快速调试安卓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

可以看到,如我们期望打印出来了日志。

参考:

Framework本地快速编译调试

https://www.cnblogs.com/plokmju/p/7742759.html