summaryrefslogtreecommitdiff
path: root/recovery_main.cpp
diff options
context:
space:
mode:
authorTao Bao <tbao@google.com>2018-07-31 09:37:12 -0700
committerTao Bao <tbao@google.com>2018-08-06 12:35:23 -0700
commit42c45e2b66790a7fe97acf7a300b025d79f2aa57 (patch)
tree3ec91a5a43fe8933147aeda206f857b94203ef80 /recovery_main.cpp
parentf2bc68cfe1c8e182fe2d05ecc0f6c86e9ffc3984 (diff)
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
Diffstat (limited to 'recovery_main.cpp')
-rw-r--r--recovery_main.cpp28
1 files changed, 27 insertions, 1 deletions
diff --git a/recovery_main.cpp b/recovery_main.cpp
index c79d7d8d..9a9890de 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());