我們都知道recovery升級的時候,是根據升級腳本updater-script里面的函數,去一步步執行的,比如mount,format等相關的操作,有時候我們需要增加一些自己特殊的更新的接口,這時候就可能需要再單獨封裝一個函數接口,我所知道的,絕大多數的開發者,都是直接在bootable/recovery/updater/install.cpp里面的RegisterInstallFunctions里面,直接注冊一個函數,這樣功能上面是實現了,但是修改上面並不規范。
其實google給我們預留了自定義函數的接口,我們只需要按照要求就可以增加我們自己封裝的函數接口,又不改動原生的代碼。這個接口就是RegisterDeviceExtensions();在其他的一些博客中,看到的有關這個的描述很少,基本上都是一筆帶過。
RegisterDeviceExtensions():與設備相關的額外添加項,在源碼中並沒有任何實現。
其實這個說法是錯誤的,RegisterDeviceExtensions()就是google預留的接口,我們來追尋下這個函數的一些邏輯流程。
首先我們來找找RegisterDeviceExtensions()的定義在哪里,我們發現bootable/recovery/updater/updater.cpp里面有個文件包含:
// Generated by the makefile, this function defines the // RegisterDeviceExtensions() function, which calls all the // registration functions for device-specific extensions. #include "register.inc"
我們通過注釋,發現了這個register.inc是跟RegisterDeviceExtensions()函數定義有關的,我們在out目錄下find下,發現了register.inc這個文件,打開這個文件,發現是個空的函數定義(obj/PACKAGING/updater_extensions_intermediates/register.inc):
void RegisterDeviceExtensions() { }
我們發現bootable/recovery/updater下面的Android.mk也有RegisterDeviceExtensions()相關的定義實現:
$(inc) : libs := $(TARGET_RECOVERY_UPDATER_LIBS)
$(inc) : $(inc_dep_file)
$(hide) mkdir -p $(dir $@)
$(hide) echo "" > $@
$(hide) $(foreach lib,$(libs),echo "extern void Register_$(lib)(void);" >> $@;)
$(hide) echo "void RegisterDeviceExtensions() {" >> $@
$(hide) $(foreach lib,$(libs),echo " Register_$(lib)();" >> $@;)
$(hide) echo "}" >> $@
我們發現register.inc就是在這里生成的,如果定義了TARGET_RECOVERY_UPDATER_LIBS這個變量,那么就會在RegisterDeviceExtensions()調用這個變量的注冊函數Register_$(lib)();
視乎有些明白了,我們把自己需要的增加的函數接口生成一個庫updater_lib1,然后把這個庫定義成updater的依賴庫,updater_lib1里面的api定義為Register_updater_lib1(),那么這個注冊函數Register_updater_lib1()就會被RegisterDeviceExtensions()調用,而RegisterDeviceExtensions()就跟原生的RegisterInstallFunctions()一樣了。
現在我們重新來理一下思路:
我們把需要增加的函數(write_logo_image)的實現封裝在一個庫update_lib1里面,這個庫update_lib1里面有個注冊函數Register_updater_lib1()去注冊write_logo_image。
Value* WriteLogoImageFn(const char* name, State* state, int argc, Expr* argv[]) { } void Register_updater_lib1() { RegisterFunction("write_logo_image", WriteLogoImageFn); }
然后把updater_lib1作為updater的依賴:
TARGET_RECOVERY_UPDATER_LIBS := updater_lib1
這樣register.inc即為:
extern void Register_updater_lib1(void); void RegisterDeviceExtensions() { Register_updater_lib1(); }
調用RegisterDeviceExtensions()即為注冊自定義的安裝函數接口。
通過上述方法修改,直接不用修改bootable/recovery/updater下面的任何代碼,就可以增加我們需要的函數接口,盡量保證不修改google原生的代碼。