am 82f479d0: Merge "Cleaner controls between Vpn and init services." into jb-mr1-dev
* commit '82f479d0647855148af84fe2ba5484cb188c92cc': Cleaner controls between Vpn and init services.
This commit is contained in:
@@ -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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user