Merge "Frameworks: Handle exceptions in SystemProperties callbacks"
This commit is contained in:
@@ -189,7 +189,12 @@ public class SystemProperties {
|
||||
}
|
||||
ArrayList<Runnable> callbacks = new ArrayList<Runnable>(sChangeCallbacks);
|
||||
for (int i=0; i<callbacks.size(); i++) {
|
||||
callbacks.get(i).run();
|
||||
try {
|
||||
callbacks.get(i).run();
|
||||
} catch (Throwable t) {
|
||||
Log.wtf(TAG, "Exception in SystemProperties change callback", t);
|
||||
// Ignore and try to go on.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +124,12 @@ void do_report_sysprop_change() {
|
||||
if (sVM->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0) {
|
||||
//ALOGI("Java SystemProperties: calling %p", sCallChangeCallbacks);
|
||||
env->CallStaticVoidMethod(sClazz, sCallChangeCallbacks);
|
||||
// There should not be any exceptions. But we must guarantee
|
||||
// there are none on return.
|
||||
if (env->ExceptionCheck()) {
|
||||
env->ExceptionClear();
|
||||
LOG(ERROR) << "Exception pending after sysprop_change!";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package android.os;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import android.os.SystemProperties;
|
||||
@@ -141,4 +144,48 @@ public class SystemPropertiesTest extends TestCase {
|
||||
} catch (NullPointerException npe) {
|
||||
}
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testCallbacks() {
|
||||
// Latches are not really necessary, but are easy to use.
|
||||
final CountDownLatch wait1 = new CountDownLatch(1);
|
||||
final CountDownLatch wait2 = new CountDownLatch(1);
|
||||
|
||||
Runnable r1 = new Runnable() {
|
||||
boolean done = false;
|
||||
@Override
|
||||
public void run() {
|
||||
if (done) {
|
||||
return;
|
||||
}
|
||||
done = true;
|
||||
|
||||
wait1.countDown();
|
||||
throw new RuntimeException("test");
|
||||
}
|
||||
};
|
||||
|
||||
Runnable r2 = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
wait2.countDown();
|
||||
}
|
||||
};
|
||||
|
||||
SystemProperties.addChangeCallback(r1);
|
||||
SystemProperties.addChangeCallback(r2);
|
||||
|
||||
SystemProperties.reportSyspropChanged();
|
||||
|
||||
try {
|
||||
assertTrue(wait1.await(5, TimeUnit.SECONDS));
|
||||
} catch (InterruptedException e) {
|
||||
fail("InterruptedException");
|
||||
}
|
||||
try {
|
||||
assertTrue(wait2.await(5, TimeUnit.SECONDS));
|
||||
} catch (InterruptedException e) {
|
||||
fail("InterruptedException");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user