Merge "Change which backdoor the tests goes through"

main
Jean Chalard 2013-04-02 09:36:02 +00:00 committed by Android (Google) Code Review
commit 868805aec4
1 changed files with 12 additions and 8 deletions

View File

@ -181,17 +181,21 @@ public class InputTestsBase extends ServiceTestCase<LatinIME> {
// a message that calls it instead of calling it directly. // a message that calls it instead of calling it directly.
Looper.loop(); Looper.loop();
// Once #quit() has been called, the message queue has an "mQuiting" field that prevents // Once #quit() has been called, the looper is not functional any more (it used to be,
// any subsequent post in this queue. However the queue itself is still fully functional! // but now it SIGSEGV's if it's used again).
// If we have a way of resetting "queue.mQuiting" then we can continue using it as normal, // It won't accept creating a new looper for this thread and switching to it...
// coming back to this method to run the messages. // ...unless we can trick it into throwing out the old looper and believing it hasn't
// been initialized before.
MessageQueue queue = Looper.myQueue(); MessageQueue queue = Looper.myQueue();
try { try {
// However there is no way of doing it externally, and mQuiting is private. // However there is no way of doing it externally, and the static ThreadLocal
// field into which it's stored is private.
// So... get out the big guns. // So... get out the big guns.
java.lang.reflect.Field f = MessageQueue.class.getDeclaredField("mQuiting"); java.lang.reflect.Field f = Looper.class.getDeclaredField("sThreadLocal");
f.setAccessible(true); // What do you mean "private"? f.setAccessible(true); // private lolwut
f.setBoolean(queue, false); final ThreadLocal<Looper> a = (ThreadLocal<Looper>) f.get(looper);
a.set(null);
looper.prepare();
} catch (NoSuchFieldException e) { } catch (NoSuchFieldException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {