Dynamically load device-specific recovery UI lib.
We used to statically link the device-specific recovery UI extension (`TARGET_RECOVERY_UI_LIB`) into `recovery`. Such a logic can't be easily migrated to Soong, as modules specified by `TARGET_RECOVERY_UI_LIB` may not be built with Soong. Instead of porting all the device-specific codes over, this CL builds and installs the UI lib as a shared library with Android.mk. `recovery` dlopen(3)'s and dlsym(3)'s `make_device` to invoke the device-specific UI lib on start. Note that in order to make dlopen(3) actually working, we have to switch `recovery` to be dynamically linked (we will make the move later anyway). Bug: 110380063 Test: Build and boot into marlin recovery image. Check that device-specific recovery UI is successfully loaded. Change-Id: Ia9861c7559a95f3f50676534540c0cb87cae4574
This commit is contained in:
parent
f2bc68cfe1
commit
42c45e2b66
4 changed files with 111 additions and 8 deletions
85
Android.mk
85
Android.mk
|
@ -28,6 +28,64 @@ recovery_common_cflags := \
|
|||
-Werror \
|
||||
-DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION)
|
||||
|
||||
# librecovery_ui_ext (shared library)
|
||||
# ===================================
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := librecovery_ui_ext
|
||||
|
||||
# LOCAL_MODULE_PATH for shared libraries is unsupported in multiarch builds.
|
||||
LOCAL_MULTILIB := first
|
||||
|
||||
ifeq ($(TARGET_IS_64_BIT),true)
|
||||
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/lib64
|
||||
else
|
||||
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/lib
|
||||
endif
|
||||
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := \
|
||||
$(TARGET_RECOVERY_UI_LIB)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libbase \
|
||||
liblog \
|
||||
librecovery_ui
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
# librecovery_ui (shared library)
|
||||
# ===============================
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := \
|
||||
device.cpp \
|
||||
screen_ui.cpp \
|
||||
ui.cpp \
|
||||
vr_ui.cpp \
|
||||
wear_ui.cpp
|
||||
|
||||
LOCAL_MODULE := librecovery_ui
|
||||
|
||||
LOCAL_CFLAGS := $(recovery_common_cflags)
|
||||
|
||||
LOCAL_MULTILIB := first
|
||||
|
||||
ifeq ($(TARGET_IS_64_BIT),true)
|
||||
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/lib64
|
||||
else
|
||||
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/lib
|
||||
endif
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
libminui \
|
||||
libotautil \
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libbase \
|
||||
libpng \
|
||||
libz \
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
# librecovery_ui (static library)
|
||||
# ===============================
|
||||
include $(CLEAR_VARS)
|
||||
|
@ -40,21 +98,23 @@ LOCAL_SRC_FILES := \
|
|||
|
||||
LOCAL_MODULE := librecovery_ui
|
||||
|
||||
LOCAL_CFLAGS := $(recovery_common_cflags)
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
libminui \
|
||||
libotautil \
|
||||
libbase
|
||||
|
||||
LOCAL_CFLAGS := $(recovery_common_cflags)
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libbase \
|
||||
libpng \
|
||||
libz \
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
librecovery_static_libraries := \
|
||||
$(TARGET_RECOVERY_UI_LIB) \
|
||||
libbootloader_message \
|
||||
libfusesideload \
|
||||
libminadbd \
|
||||
librecovery_ui \
|
||||
libminui \
|
||||
libverifier \
|
||||
libotautil \
|
||||
|
@ -112,8 +172,6 @@ LOCAL_SRC_FILES := \
|
|||
|
||||
LOCAL_MODULE := recovery
|
||||
|
||||
LOCAL_FORCE_STATIC_EXECUTABLE := true
|
||||
|
||||
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/bin
|
||||
|
||||
# Cannot link with LLD: undefined symbol: UsbNoPermissionsLongHelpText
|
||||
|
@ -124,8 +182,12 @@ LOCAL_CFLAGS := $(recovery_common_cflags)
|
|||
|
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
librecovery \
|
||||
librecovery_ui_default \
|
||||
$(librecovery_static_libraries)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
librecovery_ui \
|
||||
|
||||
LOCAL_HAL_STATIC_LIBRARIES := libhealthd
|
||||
|
||||
LOCAL_REQUIRED_MODULES := \
|
||||
|
@ -154,6 +216,17 @@ LOCAL_REQUIRED_MODULES += \
|
|||
recovery-refresh
|
||||
endif
|
||||
|
||||
LOCAL_REQUIRED_MODULES += \
|
||||
librecovery_ui_ext
|
||||
|
||||
# TODO(b/110380063): Explicitly install the following shared libraries to recovery, until `recovery`
|
||||
# module is built with Soong (with `recovery: true` flag).
|
||||
LOCAL_REQUIRED_MODULES += \
|
||||
libbase.recovery \
|
||||
liblog.recovery \
|
||||
libpng.recovery \
|
||||
libz.recovery \
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include \
|
||||
|
|
4
device.h
4
device.h
|
@ -119,8 +119,12 @@ class Device {
|
|||
std::unique_ptr<RecoveryUI> ui_;
|
||||
};
|
||||
|
||||
// Disable name mangling, as this function will be loaded via dlsym(3).
|
||||
extern "C" {
|
||||
|
||||
// The device-specific library must define this function (or the default one will be used, if there
|
||||
// is no device-specific library). It returns the Device object that recovery should use.
|
||||
Device* make_device();
|
||||
}
|
||||
|
||||
#endif // _DEVICE_H
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
|
@ -329,7 +330,32 @@ int main(int argc, char** argv) {
|
|||
|
||||
printf("locale is [%s]\n", locale.c_str());
|
||||
|
||||
Device* device = make_device();
|
||||
static constexpr const char* kDefaultLibRecoveryUIExt = "librecovery_ui_ext.so";
|
||||
// Intentionally not calling dlclose(3) to avoid potential gotchas (e.g. `make_device` may have
|
||||
// handed out pointers to code or static [or thread-local] data and doesn't collect them all back
|
||||
// in on dlclose).
|
||||
void* librecovery_ui_ext = dlopen(kDefaultLibRecoveryUIExt, RTLD_NOW);
|
||||
|
||||
using MakeDeviceType = decltype(&make_device);
|
||||
MakeDeviceType make_device_func = nullptr;
|
||||
if (librecovery_ui_ext == nullptr) {
|
||||
printf("Failed to dlopen %s: %s\n", kDefaultLibRecoveryUIExt, dlerror());
|
||||
} else {
|
||||
reinterpret_cast<void*&>(make_device_func) = dlsym(librecovery_ui_ext, "make_device");
|
||||
if (make_device_func == nullptr) {
|
||||
printf("Failed to dlsym make_device: %s\n", dlerror());
|
||||
}
|
||||
}
|
||||
|
||||
Device* device;
|
||||
if (make_device_func == nullptr) {
|
||||
printf("Falling back to the default make_device() instead\n");
|
||||
device = make_device();
|
||||
} else {
|
||||
printf("Loading make_device from %s\n", kDefaultLibRecoveryUIExt);
|
||||
device = (*make_device_func)();
|
||||
}
|
||||
|
||||
if (android::base::GetBoolProperty("ro.boot.quiescent", false)) {
|
||||
printf("Quiescent recovery mode.\n");
|
||||
device->ResetUI(new StubRecoveryUI());
|
||||
|
|
|
@ -155,10 +155,10 @@ libupdater_static_libraries := \
|
|||
|
||||
librecovery_static_libraries := \
|
||||
librecovery \
|
||||
$(TARGET_RECOVERY_UI_LIB) \
|
||||
libbootloader_message \
|
||||
libfusesideload \
|
||||
libminadbd \
|
||||
librecovery_ui_default \
|
||||
librecovery_ui \
|
||||
libminui \
|
||||
libverifier \
|
||||
|
|
Loading…
Reference in a new issue