diff options
| author | Jeff Sharkey <jsharkey@android.com> | 2012-08-05 14:55:04 -0700 |
|---|---|---|
| committer | Jeff Sharkey <jsharkey@android.com> | 2012-08-06 14:48:49 -0700 |
| commit | 088f29f55eebc6862a4cb5dddeaefacf24f74d95 (patch) | |
| tree | c641ced2808f01868c146699259d09f3c6f10363 /core/java/android/os/SystemService.java | |
| parent | 216c181e76ee11a47a0b2a180f9af96740ab38ad (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.java | 123 |
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) { + } + } + } + } } |
