/**
* Copyright 2012 Facebook
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.facebook;
import android.os.Handler;
import android.os.HandlerThread;
public class TestBlocker extends HandlerThread {
private Exception exception;
public int signals;
private volatile Handler handler;
private TestBlocker() {
super("TestBlocker");
}
public synchronized static TestBlocker createTestBlocker() {
TestBlocker blocker = new TestBlocker();
blocker.start();
// Wait until we have a Looper and Handler.
synchronized (blocker) {
while (blocker.handler == null) {
try {
blocker.wait();
} catch (InterruptedException e) {
}
}
}
return blocker;
}
@Override
public void run() {
try {
super.run();
} catch (Exception e) {
setException(e);
}
synchronized (this) {
notifyAll();
}
}
public Handler getHandler() {
return handler;
}
public void assertSuccess() throws Exception {
Exception e = getException();
if (e != null) {
throw e;
}
}
public synchronized void signal() {
++signals;
notifyAll();
}
public void waitForSignals(int numSignals) throws Exception {
// Make sure we aren't sitting on an unhandled exception before we even start, because that means our
// thread isn't around anymore.
assertSuccess();
setException(null);
synchronized (this) {
while (getException() == null && signals < numSignals) {
try {
wait();
} catch (InterruptedException e) {
}
}
signals = 0;
}
}
public void waitForSignalsAndAssertSuccess(int numSignals) throws Exception {
waitForSignals(numSignals);
assertSuccess();
}
public synchronized Exception getException() {
return exception;
}
public synchronized void setException(Exception e) {
exception = e;
notifyAll();
}
@Override
protected void onLooperPrepared() {
synchronized (this) {
handler = new Handler(getLooper());
notifyAll();
}
}
}