Android: Exit from update_engine_client when daemon dies.
When the update_engine daemon dies or is not running,
update_engine_client now exists with an error code and prints a message
stating a daemon-side failure.
Bug: 25631767
TEST=`update_engine_client --follow` and killed update_engine
Change-Id: I7c13df56bd384d2bdbc5df402f730b2797753a10
diff --git a/update_engine_client_android.cc b/update_engine_client_android.cc
index 0193eed..5cbcd33 100644
--- a/update_engine_client_android.cc
+++ b/update_engine_client_android.cc
@@ -26,6 +26,7 @@
#include <base/logging.h>
#include <base/strings/string_split.h>
#include <binder/IServiceManager.h>
+#include <binderwrapper/binder_wrapper.h>
#include <brillo/binder_watcher.h>
#include <brillo/daemons/daemon.h>
#include <brillo/flag_helper.h>
@@ -37,8 +38,8 @@
#include "android/os/BnUpdateEngineCallback.h"
#include "android/os/IUpdateEngine.h"
#include "update_engine/client_library/include/update_engine/update_status.h"
-#include "update_engine/update_status_utils.h"
#include "update_engine/common/error_code.h"
+#include "update_engine/update_status_utils.h"
using android::binder::Status;
@@ -69,6 +70,9 @@
int OnInit() override;
+ // Called whenever the UpdateEngine daemon dies.
+ void UpdateEngineServiceDied();
+
// Copy of argc and argv passed to main().
int argc_;
char** argv_;
@@ -137,13 +141,18 @@
}
bool keep_running = false;
-
brillo::InitLog(brillo::kLogToStderr);
+
+ // Initialize a binder watcher early in the process before any interaction
+ // with the binder driver.
+ binder_watcher_.Init();
+
android::status_t status = android::getService(
android::String16("android.os.UpdateEngineService"), &service_);
if (status != android::OK) {
LOG(ERROR) << "Failed to get IUpdateEngine binder from service manager: "
<< Status::fromStatusT(status).toString8();
+ return ExitWhenIdle(1);
}
if (FLAGS_suspend) {
@@ -186,8 +195,14 @@
if (!keep_running)
return ExitWhenIdle(EX_OK);
- // Initialize a binder watcher.
- binder_watcher_.Init();
+ // When following updates status changes, exit if the update_engine daemon
+ // dies.
+ android::BinderWrapper::Create();
+ android::BinderWrapper::Get()->RegisterForDeathNotifications(
+ android::os::IUpdateEngine::asBinder(service_),
+ base::Bind(&UpdateEngineClientAndroid::UpdateEngineServiceDied,
+ base::Unretained(this)));
+
return EX_OK;
}
@@ -206,6 +221,11 @@
return EX_OK;
}
+void UpdateEngineClientAndroid::UpdateEngineServiceDied() {
+ LOG(ERROR) << "UpdateEngineService died.";
+ QuitWithExitCode(1);
+}
+
} // namespace internal
} // namespace chromeos_update_engine