Merge "Frameworks: Handle exceptions in SystemProperties callbacks"

This commit is contained in:
Treehugger Robot
2018-03-19 19:38:13 +00:00
committed by Gerrit Code Review
3 changed files with 59 additions and 1 deletions

View File

@@ -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.
}
}
}
}

View File

@@ -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!";
}
}
}
}

View File

@@ -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");
}
}
}