libsysutils: Introduce 'ServiceManager', for starting/stopping init services
Signed-off-by: San Mehat <san@google.com>
diff --git a/libsysutils/Android.mk b/libsysutils/Android.mk
index 2f3e106..dd2b32d 100644
--- a/libsysutils/Android.mk
+++ b/libsysutils/Android.mk
@@ -16,6 +16,7 @@
src/NetlinkEvent.cpp \
src/FrameworkCommand.cpp \
src/SocketClient.cpp \
+ src/ServiceManager.cpp \
LOCAL_MODULE:= libsysutils
diff --git a/libsysutils/src/ServiceManager.cpp b/libsysutils/src/ServiceManager.cpp
new file mode 100644
index 0000000..700ac91
--- /dev/null
+++ b/libsysutils/src/ServiceManager.cpp
@@ -0,0 +1,73 @@
+#include <errno.h>
+
+#include <sysutils/ServiceManager.h>
+
+#define LOG_TAG "Service"
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+ServiceManager::ServiceManager() {
+}
+
+int ServiceManager::start(const char *name) {
+ if (isRunning(name)) {
+ LOGW("Service '%s' is already running", name);
+ return 0;
+ }
+
+ LOGD("Starting service '%s'", name);
+ property_set("ctl.start", name);
+
+ int count = 200;
+ while(count--) {
+ sched_yield();
+ if (isRunning(name))
+ break;
+ }
+ if (!count) {
+ LOGW("Timed out waiting for service '%s' to start", name);
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ LOGD("Sucessfully started '%s'", name);
+ return 0;
+}
+
+int ServiceManager::stop(const char *name) {
+ if (!isRunning(name)) {
+ LOGW("Service '%s' is already stopped", name);
+ return 0;
+ }
+
+ LOGD("Stopping service '%s'", name);
+ property_set("ctl.stop", name);
+
+ int count = 200;
+ while(count--) {
+ sched_yield();
+ if (!isRunning(name))
+ break;
+ }
+
+ if (!count) {
+ LOGW("Timed out waiting for service '%s' to stop", name);
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ LOGD("Sucessfully stopped '%s'", name);
+ return 0;
+}
+
+bool ServiceManager::isRunning(const char *name) {
+ char propVal[PROPERTY_VALUE_MAX];
+ char propName[255];
+
+ snprintf(propName, sizeof(propVal), "init.svc.%s", name);
+
+
+ if (property_get(propName, propVal, NULL)) {
+ if (!strcmp(propVal, "running"))
+ return true;
+ }
+ return false;
+}