/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
* copy, modify, and distribute this software in source code or binary form for use
* in connection with the web services and APIs provided by Facebook.
*
* As with any software that integrates with the Facebook platform, your use of
* this software is subject to the Facebook Developer Principles and Policies
* [http://developers.facebook.com/policy/]. This copyright notice shall be
* included in all copies or substantial portions of the software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
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();
}
}
}