diff options
-rw-r--r-- | Android.mk | 85 | ||||
-rw-r--r-- | device.h | 4 | ||||
-rw-r--r-- | recovery_main.cpp | 28 | ||||
-rw-r--r-- | tests/Android.mk | 2 |
4 files changed, 111 insertions, 8 deletions
diff --git a/Android.mk b/Android.mk index 7b2843d17..b25c1f07a 100644 --- a/Android.mk +++ b/Android.mk @@ -28,7 +28,32 @@ recovery_common_cflags := \ -Werror \ -DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION) -# librecovery_ui (static library) +# 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 := \ @@ -40,13 +65,50 @@ LOCAL_SRC_FILES := \ 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 \ - libbase + +LOCAL_SHARED_LIBRARIES := \ + libbase \ + libpng \ + libz \ + +include $(BUILD_SHARED_LIBRARY) + +# librecovery_ui (static 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_STATIC_LIBRARIES := \ + libminui \ + libotautil \ + +LOCAL_SHARED_LIBRARIES := \ + libbase \ + libpng \ + libz \ + include $(BUILD_STATIC_LIBRARY) # Health HAL dependency @@ -63,11 +125,9 @@ health_hal_static_libraries := \ libbatterymonitor librecovery_static_libraries := \ - $(TARGET_RECOVERY_UI_LIB) \ libbootloader_message \ libfusesideload \ libminadbd \ - librecovery_ui \ libminui \ libverifier \ libotautil \ @@ -125,8 +185,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 @@ -137,8 +195,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 := \ @@ -167,6 +229,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 \ @@ -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 diff --git a/recovery_main.cpp b/recovery_main.cpp index c79d7d8d8..9a9890de0 100644 --- a/recovery_main.cpp +++ b/recovery_main.cpp @@ -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()); diff --git a/tests/Android.mk b/tests/Android.mk index 93286ea0d..8148e9022 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -167,10 +167,10 @@ health_hal_static_libraries := \ librecovery_static_libraries := \ librecovery \ - $(TARGET_RECOVERY_UI_LIB) \ libbootloader_message \ libfusesideload \ libminadbd \ + librecovery_ui_default \ librecovery_ui \ libminui \ libverifier \ |