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