'Can I write a system property listener in android?
Having set a system property in android using the setprop command (through adb) is there a way to listen to this change in my own service?
I tried with SystemProperties.addChangeCallback and was not notified. Was there something that I missed?
Solution 1:[1]
You can create a method in your service which should fetch any Systemproperty and that method should call Looper.loop(); so that that loop will poll for SystemProperty time to time This implementation may not be optimized way of doing this but it is used in Android 4.4.2, you can see here http://androidxref.com/4.4.2_r2/xref/frameworks/base/services/java/com/android/server/SystemServer.java you can see at above link:
boolean disableStorage = SystemProperties.getBoolean("config.disable_storage", false);
boolean disableMedia = SystemProperties.getBoolean("config.disable_media", false);
boolean disableBluetooth = SystemProperties.getBoolean("config.disable_bluetooth", false);
boolean disableTelephony = SystemProperties.getBoolean("config.disable_telephony", false);
boolean disableLocation = SystemProperties.getBoolean("config.disable_location", false);
boolean disableSystemUI = SystemProperties.getBoolean("config.disable_systemui", false);
boolean disableNonCoreServices = SystemProperties.getBoolean("config.disable_noncore", false);
boolean disableNetwork = SystemProperties.getBoolean("config.disable_network", false);
These boolean variables are being checked in initAndLoop() method with the help of Looper.loop(); here you can notify your other components on any change in even a single SystemProperty.
Another way is to create static callback and get call for any change in any of SystemProperty, see the master branch's code for SystemService here: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/os/SystemService.java
you can see in above link what following code is doing:
private static Object sPropertyLock = new Object();
static {
SystemProperties.addChangeCallback(new Runnable() {
@Override
public void run() {
synchronized (sPropertyLock) {
sPropertyLock.notifyAll();
}
}
});
}
/**
* 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) {
}
}
}
}
This information originates from Shridutt Kothari. Check this google post about listening to single SystemProperty changes
Solution 2:[2]
Too long for comments, so adding as an answer:
The setprop tool does not appear to fire change callbacks. In my read of the OS source, it simply sets a property value in a hashmap (see: https://cs.android.com/android/platform/superproject/+/master:system/libbase/properties.cpp;bpv=1;bpt=1;l=133?q=setprop).
For the callback to happen, someone needs to call do_report_sysprop_change (https://cs.android.com/android/platform/superproject/+/master:system/core/libutils/misc.cpp;bpv=1;bpt=1;l=102?q=syspropchange&ss=android%2Fplatform%2Fsuperproject&gsn=do_report_sysprop_change&gs=kythe%3A%2F%2Fandroid.googlesource.com%2Fplatform%2Fsuperproject%3Flang%3Dc%252B%252B%3Fpath%3Dsystem%2Fcore%2Flibutils%2Fmisc.cpp%23tC5_BHx-Z-jKUw_rRXWlL0wtVyVh15Oh60E0YnrdfSg&gs=kythe%3A%2F%2Fandroid.googlesource.com%2Fplatform%2Fsuperproject%3Flang%3Dc%252B%252B%3Fpath%3Dsystem%2Fcore%2Flibutils%2Fmisc.cpp%234FfZ9jgPIUEg7IKCGYGLCaQ4-cj6enFs8AeI7SIRLBs) and this is not done via setprop. I do see it invoked in a variety of places in the OS since invocation of the set prop callback is a method in the IBase interface implemented by a variety of services in Android.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | jobbert |
| Solution 2 | scorpiodawg |
