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;
|
package android.os;
|
||||||
|
|
||||||
/** @hide */
|
import com.google.android.collect.Maps;
|
||||||
public class SystemService
|
|
||||||
{
|
import java.util.HashMap;
|
||||||
/** Request that the init daemon start a named service. */
|
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) {
|
public static void start(String name) {
|
||||||
SystemProperties.set("ctl.start", 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) {
|
public static void stop(String name) {
|
||||||
SystemProperties.set("ctl.stop", name);
|
SystemProperties.set("ctl.stop", name);
|
||||||
}
|
}
|
||||||
@@ -33,4 +71,77 @@ public class SystemService
|
|||||||
public static void restart(String name) {
|
public static void restart(String name) {
|
||||||
SystemProperties.set("ctl.restart", 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.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
@@ -39,7 +38,7 @@ import android.os.Parcel;
|
|||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemService;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
@@ -485,8 +484,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
|
|||||||
|
|
||||||
// Wait for the daemons to stop.
|
// Wait for the daemons to stop.
|
||||||
for (String daemon : mDaemons) {
|
for (String daemon : mDaemons) {
|
||||||
String key = "init.svc." + daemon;
|
while (!SystemService.isStopped(daemon)) {
|
||||||
while (!"stopped".equals(SystemProperties.get(key, "stopped"))) {
|
|
||||||
checkpoint(true);
|
checkpoint(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -519,11 +517,10 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
|
|||||||
|
|
||||||
// Start the daemon.
|
// Start the daemon.
|
||||||
String daemon = mDaemons[i];
|
String daemon = mDaemons[i];
|
||||||
SystemProperties.set("ctl.start", daemon);
|
SystemService.start(daemon);
|
||||||
|
|
||||||
// Wait for the daemon to start.
|
// Wait for the daemon to start.
|
||||||
String key = "init.svc." + daemon;
|
while (!SystemService.isRunning(daemon)) {
|
||||||
while (!"running".equals(SystemProperties.get(key))) {
|
|
||||||
checkpoint(true);
|
checkpoint(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -579,8 +576,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
|
|||||||
// Check if a running daemon is dead.
|
// Check if a running daemon is dead.
|
||||||
for (int i = 0; i < mDaemons.length; ++i) {
|
for (int i = 0; i < mDaemons.length; ++i) {
|
||||||
String daemon = mDaemons[i];
|
String daemon = mDaemons[i];
|
||||||
if (mArguments[i] != null && !"running".equals(
|
if (mArguments[i] != null && !SystemService.isRunning(daemon)) {
|
||||||
SystemProperties.get("init.svc." + daemon))) {
|
|
||||||
throw new IllegalStateException(daemon + " is dead");
|
throw new IllegalStateException(daemon + " is dead");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -647,7 +643,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
|
|||||||
// Kill the daemons if they fail to stop.
|
// Kill the daemons if they fail to stop.
|
||||||
if (mInfo.state == LegacyVpnInfo.STATE_INITIALIZING) {
|
if (mInfo.state == LegacyVpnInfo.STATE_INITIALIZING) {
|
||||||
for (String daemon : mDaemons) {
|
for (String daemon : mDaemons) {
|
||||||
SystemProperties.set("ctl.stop", daemon);
|
SystemService.stop(daemon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user