summaryrefslogtreecommitdiff
path: root/core/java/android/os/SystemService.java
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2012-08-05 14:55:04 -0700
committerJeff Sharkey <jsharkey@android.com>2012-08-06 14:48:49 -0700
commit088f29f55eebc6862a4cb5dddeaefacf24f74d95 (patch)
treec641ced2808f01868c146699259d09f3c6f10363 /core/java/android/os/SystemService.java
parent216c181e76ee11a47a0b2a180f9af96740ab38ad (diff)
Cleaner controls between Vpn and init services.
Change-Id: I35edf054f4a1190f7fb7b4c48ee832e899c9528b
Diffstat (limited to 'core/java/android/os/SystemService.java')
-rw-r--r--core/java/android/os/SystemService.java123
1 files changed, 117 insertions, 6 deletions
diff --git a/core/java/android/os/SystemService.java b/core/java/android/os/SystemService.java
index da27db55c49a..db58012d47ab 100644
--- a/core/java/android/os/SystemService.java
+++ b/core/java/android/os/SystemService.java
@@ -16,15 +16,53 @@
package android.os;
-/** @hide */
-public class SystemService
-{
- /** Request that the init daemon start a named service. */
+import com.google.android.collect.Maps;
+
+import java.util.HashMap;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Controls and utilities for low-level {@code init} services.
+ *
+ * @hide
+ */
+public class SystemService {
+
+ private static HashMap<String, State> sStates = Maps.newHashMap();
+
+ /**
+ * State of a known {@code init} service.
+ */
+ public enum State {
+ RUNNING("running"),
+ STOPPING("stopping"),
+ STOPPED("stopped"),
+ RESTARTING("restarting");
+
+ State(String state) {
+ sStates.put(state, this);
+ }
+ }
+
+ private static Object sPropertyLock = new Object();
+
+ static {
+ SystemProperties.addChangeCallback(new Runnable() {
+ @Override
+ public void run() {
+ synchronized (sPropertyLock) {
+ sPropertyLock.notifyAll();
+ }
+ }
+ });
+ }
+
+ /** Request that the init daemon start a named service. */
public static void start(String name) {
SystemProperties.set("ctl.start", name);
}
-
- /** Request that the init daemon stop a named service. */
+
+ /** Request that the init daemon stop a named service. */
public static void stop(String name) {
SystemProperties.set("ctl.stop", name);
}
@@ -33,4 +71,77 @@ public class SystemService
public static void restart(String name) {
SystemProperties.set("ctl.restart", name);
}
+
+ /**
+ * Return current state of given service.
+ */
+ public static State getState(String service) {
+ final String rawState = SystemProperties.get("init.svc." + service);
+ final State state = sStates.get(rawState);
+ if (state != null) {
+ return state;
+ } else {
+ throw new IllegalStateException("Service " + service + " in unknown state " + rawState);
+ }
+ }
+
+ /**
+ * Check if given service is {@link State#STOPPED}.
+ */
+ public static boolean isStopped(String service) {
+ return State.STOPPED.equals(getState(service));
+ }
+
+ /**
+ * Check if given service is {@link State#RUNNING}.
+ */
+ public static boolean isRunning(String service) {
+ return State.RUNNING.equals(getState(service));
+ }
+
+ /**
+ * Wait until given service has entered specific state.
+ */
+ public static void waitForState(String service, State state, long timeoutMillis)
+ throws TimeoutException {
+ final long endMillis = SystemClock.elapsedRealtime() + timeoutMillis;
+ while (true) {
+ synchronized (sPropertyLock) {
+ final State currentState = getState(service);
+ if (state.equals(currentState)) {
+ return;
+ }
+
+ if (SystemClock.elapsedRealtime() >= endMillis) {
+ throw new TimeoutException("Service " + service + " currently " + currentState
+ + "; waited " + timeoutMillis + "ms for " + state);
+ }
+
+ try {
+ sPropertyLock.wait(timeoutMillis);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Wait until any of given services enters {@link State#STOPPED}.
+ */
+ public static void waitForAnyStopped(String... services) {
+ while (true) {
+ synchronized (sPropertyLock) {
+ for (String service : services) {
+ if (State.STOPPED.equals(getState(service))) {
+ return;
+ }
+ }
+
+ try {
+ sPropertyLock.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ }
}