summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sysutils/ServiceManager.h30
-rw-r--r--libsysutils/Android.mk1
-rw-r--r--libsysutils/src/ServiceManager.cpp73
3 files changed, 104 insertions, 0 deletions
diff --git a/include/sysutils/ServiceManager.h b/include/sysutils/ServiceManager.h
new file mode 100644
index 0000000..c31dd8f
--- /dev/null
+++ b/include/sysutils/ServiceManager.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _SERVICE_MANAGER_H
+#define _SERVICE_MANAGER_H
+
+class ServiceManager {
+public:
+ ServiceManager();
+ virtual ~ServiceManager() {}
+
+ int start(const char *name);
+ int stop(const char *name);
+ bool isRunning(const char *name);
+};
+
+#endif
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 @@ LOCAL_SRC_FILES:= \
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;
+}