Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a3c96c15 authored by Andreas Gampe's avatar Andreas Gampe Committed by android-build-merger
Browse files

Merge "Frameworks: Handle exceptions in SystemProperties callbacks" am: af3dc4fc

am: bccdf32c

Change-Id: Ie640cf1734ff80a19d8c0ba65734f5e76d26fa76
parents a809ae38 bccdf32c
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -205,7 +205,12 @@ public class SystemProperties {
            }
            ArrayList<Runnable> callbacks = new ArrayList<Runnable>(sChangeCallbacks);
            for (int i=0; i<callbacks.size(); i++) {
                try {
                    callbacks.get(i).run();
                } catch (Throwable t) {
                    Log.wtf(TAG, "Exception in SystemProperties change callback", t);
                    // Ignore and try to go on.
                }
            }
        }
    }
+6 −0
Original line number Diff line number Diff line
@@ -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!";
            }
        }
    }
}
+47 −0
Original line number Diff line number Diff line
@@ -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");
        }
    }
}