Skip to content

Commit 82f479d

Browse files
jsharkeyAndroid (Google) Code Review
authored andcommitted
Merge "Cleaner controls between Vpn and init services." into jb-mr1-dev
2 parents f3c16a1 + 088f29f commit 82f479d

File tree

2 files changed

+123
-16
lines changed

2 files changed

+123
-16
lines changed

core/java/android/os/SystemService.java

Lines changed: 117 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,53 @@
1616

1717
package android.os;
1818

19-
/** @hide */
20-
public class SystemService
21-
{
22-
/** Request that the init daemon start a named service. */
19+
import com.google.android.collect.Maps;
20+
21+
import java.util.HashMap;
22+
import java.util.concurrent.TimeoutException;
23+
24+
/**
25+
* Controls and utilities for low-level {@code init} services.
26+
*
27+
* @hide
28+
*/
29+
public class SystemService {
30+
31+
private static HashMap<String, State> sStates = Maps.newHashMap();
32+
33+
/**
34+
* State of a known {@code init} service.
35+
*/
36+
public enum State {
37+
RUNNING("running"),
38+
STOPPING("stopping"),
39+
STOPPED("stopped"),
40+
RESTARTING("restarting");
41+
42+
State(String state) {
43+
sStates.put(state, this);
44+
}
45+
}
46+
47+
private static Object sPropertyLock = new Object();
48+
49+
static {
50+
SystemProperties.addChangeCallback(new Runnable() {
51+
@Override
52+
public void run() {
53+
synchronized (sPropertyLock) {
54+
sPropertyLock.notifyAll();
55+
}
56+
}
57+
});
58+
}
59+
60+
/** Request that the init daemon start a named service. */
2361
public static void start(String name) {
2462
SystemProperties.set("ctl.start", name);
2563
}
26-
27-
/** Request that the init daemon stop a named service. */
64+
65+
/** Request that the init daemon stop a named service. */
2866
public static void stop(String name) {
2967
SystemProperties.set("ctl.stop", name);
3068
}
@@ -33,4 +71,77 @@ public static void stop(String name) {
3371
public static void restart(String name) {
3472
SystemProperties.set("ctl.restart", name);
3573
}
74+
75+
/**
76+
* Return current state of given service.
77+
*/
78+
public static State getState(String service) {
79+
final String rawState = SystemProperties.get("init.svc." + service);
80+
final State state = sStates.get(rawState);
81+
if (state != null) {
82+
return state;
83+
} else {
84+
throw new IllegalStateException("Service " + service + " in unknown state " + rawState);
85+
}
86+
}
87+
88+
/**
89+
* Check if given service is {@link State#STOPPED}.
90+
*/
91+
public static boolean isStopped(String service) {
92+
return State.STOPPED.equals(getState(service));
93+
}
94+
95+
/**
96+
* Check if given service is {@link State#RUNNING}.
97+
*/
98+
public static boolean isRunning(String service) {
99+
return State.RUNNING.equals(getState(service));
100+
}
101+
102+
/**
103+
* Wait until given service has entered specific state.
104+
*/
105+
public static void waitForState(String service, State state, long timeoutMillis)
106+
throws TimeoutException {
107+
final long endMillis = SystemClock.elapsedRealtime() + timeoutMillis;
108+
while (true) {
109+
synchronized (sPropertyLock) {
110+
final State currentState = getState(service);
111+
if (state.equals(currentState)) {
112+
return;
113+
}
114+
115+
if (SystemClock.elapsedRealtime() >= endMillis) {
116+
throw new TimeoutException("Service " + service + " currently " + currentState
117+
+ "; waited " + timeoutMillis + "ms for " + state);
118+
}
119+
120+
try {
121+
sPropertyLock.wait(timeoutMillis);
122+
} catch (InterruptedException e) {
123+
}
124+
}
125+
}
126+
}
127+
128+
/**
129+
* Wait until any of given services enters {@link State#STOPPED}.
130+
*/
131+
public static void waitForAnyStopped(String... services) {
132+
while (true) {
133+
synchronized (sPropertyLock) {
134+
for (String service : services) {
135+
if (State.STOPPED.equals(getState(service))) {
136+
return;
137+
}
138+
}
139+
140+
try {
141+
sPropertyLock.wait();
142+
} catch (InterruptedException e) {
143+
}
144+
}
145+
}
146+
}
36147
}

services/java/com/android/server/connectivity/Vpn.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import android.content.pm.ApplicationInfo;
2626
import android.content.pm.PackageManager;
2727
import android.content.pm.ResolveInfo;
28-
import android.content.res.Resources;
2928
import android.graphics.Bitmap;
3029
import android.graphics.Canvas;
3130
import android.graphics.drawable.Drawable;
@@ -39,7 +38,7 @@
3938
import android.os.ParcelFileDescriptor;
4039
import android.os.Process;
4140
import android.os.SystemClock;
42-
import android.os.SystemProperties;
41+
import android.os.SystemService;
4342
import android.util.Log;
4443

4544
import com.android.internal.R;
@@ -485,8 +484,7 @@ private void execute() {
485484

486485
// Wait for the daemons to stop.
487486
for (String daemon : mDaemons) {
488-
String key = "init.svc." + daemon;
489-
while (!"stopped".equals(SystemProperties.get(key, "stopped"))) {
487+
while (!SystemService.isStopped(daemon)) {
490488
checkpoint(true);
491489
}
492490
}
@@ -519,11 +517,10 @@ private void execute() {
519517

520518
// Start the daemon.
521519
String daemon = mDaemons[i];
522-
SystemProperties.set("ctl.start", daemon);
520+
SystemService.start(daemon);
523521

524522
// Wait for the daemon to start.
525-
String key = "init.svc." + daemon;
526-
while (!"running".equals(SystemProperties.get(key))) {
523+
while (!SystemService.isRunning(daemon)) {
527524
checkpoint(true);
528525
}
529526

@@ -579,8 +576,7 @@ private void execute() {
579576
// Check if a running daemon is dead.
580577
for (int i = 0; i < mDaemons.length; ++i) {
581578
String daemon = mDaemons[i];
582-
if (mArguments[i] != null && !"running".equals(
583-
SystemProperties.get("init.svc." + daemon))) {
579+
if (mArguments[i] != null && !SystemService.isRunning(daemon)) {
584580
throw new IllegalStateException(daemon + " is dead");
585581
}
586582
}
@@ -647,7 +643,7 @@ private void execute() {
647643
// Kill the daemons if they fail to stop.
648644
if (mInfo.state == LegacyVpnInfo.STATE_INITIALIZING) {
649645
for (String daemon : mDaemons) {
650-
SystemProperties.set("ctl.stop", daemon);
646+
SystemService.stop(daemon);
651647
}
652648
}
653649

0 commit comments

Comments
 (0)