Loading core/java/android/os/SystemService.java +117 −6 Original line number Diff line number Diff line Loading @@ -16,9 +16,47 @@ package android.os; /** @hide */ public class SystemService { 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); Loading @@ -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) { } } } } } services/java/com/android/server/connectivity/Vpn.java +6 −10 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import android.content.ServiceConnection; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.drawable.Drawable; Loading @@ -39,7 +38,7 @@ import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.SystemClock; import android.os.SystemProperties; import android.os.SystemService; import android.util.Log; import com.android.internal.R; Loading Loading @@ -485,8 +484,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub { // Wait for the daemons to stop. for (String daemon : mDaemons) { String key = "init.svc." + daemon; while (!"stopped".equals(SystemProperties.get(key, "stopped"))) { while (!SystemService.isStopped(daemon)) { checkpoint(true); } } Loading Loading @@ -519,11 +517,10 @@ public class Vpn extends INetworkManagementEventObserver.Stub { // Start the daemon. String daemon = mDaemons[i]; SystemProperties.set("ctl.start", daemon); SystemService.start(daemon); // Wait for the daemon to start. String key = "init.svc." + daemon; while (!"running".equals(SystemProperties.get(key))) { while (!SystemService.isRunning(daemon)) { checkpoint(true); } Loading Loading @@ -579,8 +576,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub { // Check if a running daemon is dead. for (int i = 0; i < mDaemons.length; ++i) { String daemon = mDaemons[i]; if (mArguments[i] != null && !"running".equals( SystemProperties.get("init.svc." + daemon))) { if (mArguments[i] != null && !SystemService.isRunning(daemon)) { throw new IllegalStateException(daemon + " is dead"); } } Loading Loading @@ -647,7 +643,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub { // Kill the daemons if they fail to stop. if (mInfo.state == LegacyVpnInfo.STATE_INITIALIZING) { for (String daemon : mDaemons) { SystemProperties.set("ctl.stop", daemon); SystemService.stop(daemon); } } Loading Loading
core/java/android/os/SystemService.java +117 −6 Original line number Diff line number Diff line Loading @@ -16,9 +16,47 @@ package android.os; /** @hide */ public class SystemService { 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); Loading @@ -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) { } } } } }
services/java/com/android/server/connectivity/Vpn.java +6 −10 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import android.content.ServiceConnection; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.drawable.Drawable; Loading @@ -39,7 +38,7 @@ import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.SystemClock; import android.os.SystemProperties; import android.os.SystemService; import android.util.Log; import com.android.internal.R; Loading Loading @@ -485,8 +484,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub { // Wait for the daemons to stop. for (String daemon : mDaemons) { String key = "init.svc." + daemon; while (!"stopped".equals(SystemProperties.get(key, "stopped"))) { while (!SystemService.isStopped(daemon)) { checkpoint(true); } } Loading Loading @@ -519,11 +517,10 @@ public class Vpn extends INetworkManagementEventObserver.Stub { // Start the daemon. String daemon = mDaemons[i]; SystemProperties.set("ctl.start", daemon); SystemService.start(daemon); // Wait for the daemon to start. String key = "init.svc." + daemon; while (!"running".equals(SystemProperties.get(key))) { while (!SystemService.isRunning(daemon)) { checkpoint(true); } Loading Loading @@ -579,8 +576,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub { // Check if a running daemon is dead. for (int i = 0; i < mDaemons.length; ++i) { String daemon = mDaemons[i]; if (mArguments[i] != null && !"running".equals( SystemProperties.get("init.svc." + daemon))) { if (mArguments[i] != null && !SystemService.isRunning(daemon)) { throw new IllegalStateException(daemon + " is dead"); } } Loading Loading @@ -647,7 +643,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub { // Kill the daemons if they fail to stop. if (mInfo.state == LegacyVpnInfo.STATE_INITIALIZING) { for (String daemon : mDaemons) { SystemProperties.set("ctl.stop", daemon); SystemService.stop(daemon); } } Loading