• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.os;
18 
19 import com.google.android.collect.Maps;
20 
21 import android.annotation.UnsupportedAppUsage;
22 import java.util.HashMap;
23 import java.util.concurrent.TimeoutException;
24 
25 /**
26  * Controls and utilities for low-level {@code init} services.
27  *
28  * @hide
29  */
30 public class SystemService {
31 
32     private static HashMap<String, State> sStates = Maps.newHashMap();
33 
34     /**
35      * State of a known {@code init} service.
36      */
37     public enum State {
38         RUNNING("running"),
39         STOPPING("stopping"),
40         STOPPED("stopped"),
41         RESTARTING("restarting");
42 
State(String state)43         State(String state) {
44             sStates.put(state, this);
45         }
46     }
47 
48     private static Object sPropertyLock = new Object();
49 
50     static {
SystemProperties.addChangeCallback(new Runnable() { @Override public void run() { synchronized (sPropertyLock) { sPropertyLock.notifyAll(); } } })51         SystemProperties.addChangeCallback(new Runnable() {
52             @Override
53             public void run() {
54                 synchronized (sPropertyLock) {
55                     sPropertyLock.notifyAll();
56                 }
57             }
58         });
59     }
60 
61     /** Request that the init daemon start a named service. */
62     @UnsupportedAppUsage
start(String name)63     public static void start(String name) {
64         SystemProperties.set("ctl.start", name);
65     }
66 
67     /** Request that the init daemon stop a named service. */
68     @UnsupportedAppUsage
stop(String name)69     public static void stop(String name) {
70         SystemProperties.set("ctl.stop", name);
71     }
72 
73     /** Request that the init daemon restart a named service. */
restart(String name)74     public static void restart(String name) {
75         SystemProperties.set("ctl.restart", name);
76     }
77 
78     /**
79      * Return current state of given service.
80      */
getState(String service)81     public static State getState(String service) {
82         final String rawState = SystemProperties.get("init.svc." + service);
83         final State state = sStates.get(rawState);
84         if (state != null) {
85             return state;
86         } else {
87             return State.STOPPED;
88         }
89     }
90 
91     /**
92      * Check if given service is {@link State#STOPPED}.
93      */
isStopped(String service)94     public static boolean isStopped(String service) {
95         return State.STOPPED.equals(getState(service));
96     }
97 
98     /**
99      * Check if given service is {@link State#RUNNING}.
100      */
isRunning(String service)101     public static boolean isRunning(String service) {
102         return State.RUNNING.equals(getState(service));
103     }
104 
105     /**
106      * Wait until given service has entered specific state.
107      */
waitForState(String service, State state, long timeoutMillis)108     public static void waitForState(String service, State state, long timeoutMillis)
109             throws TimeoutException {
110         final long endMillis = SystemClock.elapsedRealtime() + timeoutMillis;
111         while (true) {
112             synchronized (sPropertyLock) {
113                 final State currentState = getState(service);
114                 if (state.equals(currentState)) {
115                     return;
116                 }
117 
118                 if (SystemClock.elapsedRealtime() >= endMillis) {
119                     throw new TimeoutException("Service " + service + " currently " + currentState
120                             + "; waited " + timeoutMillis + "ms for " + state);
121                 }
122 
123                 try {
124                     sPropertyLock.wait(timeoutMillis);
125                 } catch (InterruptedException e) {
126                 }
127             }
128         }
129     }
130 
131     /**
132      * Wait until any of given services enters {@link State#STOPPED}.
133      */
waitForAnyStopped(String... services)134     public static void waitForAnyStopped(String... services)  {
135         while (true) {
136             synchronized (sPropertyLock) {
137                 for (String service : services) {
138                     if (State.STOPPED.equals(getState(service))) {
139                         return;
140                     }
141                 }
142 
143                 try {
144                     sPropertyLock.wait();
145                 } catch (InterruptedException e) {
146                 }
147             }
148         }
149     }
150 }
151