14f7c51ca4c48911c24097b86932c229fa874359eSam Juddpackage com.bumptech.glide.request;
24f7c51ca4c48911c24097b86932c229fa874359eSam Judd
34f7c51ca4c48911c24097b86932c229fa874359eSam Juddimport android.graphics.drawable.Drawable;
44f7c51ca4c48911c24097b86932c229fa874359eSam Juddimport android.os.Handler;
54f7c51ca4c48911c24097b86932c229fa874359eSam Judd
65f4610b54d517be58105bcf73ce3291ba79f9f40Sam Juddimport com.bumptech.glide.request.animation.GlideAnimation;
7e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Juddimport com.bumptech.glide.request.target.SizeReadyCallback;
84f7c51ca4c48911c24097b86932c229fa874359eSam Juddimport com.bumptech.glide.util.Util;
94f7c51ca4c48911c24097b86932c229fa874359eSam Judd
104f7c51ca4c48911c24097b86932c229fa874359eSam Juddimport java.util.concurrent.CancellationException;
114f7c51ca4c48911c24097b86932c229fa874359eSam Juddimport java.util.concurrent.ExecutionException;
124f7c51ca4c48911c24097b86932c229fa874359eSam Juddimport java.util.concurrent.TimeUnit;
134f7c51ca4c48911c24097b86932c229fa874359eSam Juddimport java.util.concurrent.TimeoutException;
144f7c51ca4c48911c24097b86932c229fa874359eSam Judd
155f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd/**
165f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd * A {@link java.util.concurrent.Future} implementation for Glide that can be used to load resources in a blocking
175f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd * manner on background threads.
185f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd *
195f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd * <p>
205f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd *     Note - Unlike most targets, RequestFutureTargets can be used once and only once. Attempting to reuse a
215f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd *     RequestFutureTarget will probably result in undesirable behavior or exceptions. Instead of reusing
225f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd *     objects of this class, the pattern should be:
235f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd *
245f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd *     <pre>
255f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd *     {@code
265f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd *      RequestFutureTarget target = Glide.load("")...
275f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd *     Object resource = target.get();
285f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd *     // Do something with resource, and when finished:
295f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd *     Glide.clear(target);
305f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd *     }
315f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd *     </pre>
325f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd *     The {@link com.bumptech.glide.Glide#clear(FutureTarget)} call will make sure any resources used are recycled.
335f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd * </p>
345f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd *
355f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd * @param <T> The type of the data to load.
365f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd * @param <R> The type of the resource that will be loaded.
375f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd */
38e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Juddpublic class RequestFutureTarget<T, R> implements FutureTarget<R>, Runnable {
395ba19a0e69ad3a651b8f13ba45de48a56b56ce36Sam Judd    private static final Waiter DEFAULT_WAITER = new Waiter();
40e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd
415f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd    private final Handler mainHandler;
424f7c51ca4c48911c24097b86932c229fa874359eSam Judd    private final int width;
434f7c51ca4c48911c24097b86932c229fa874359eSam Judd    private final int height;
445f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd    // Exists for testing only.
454f7c51ca4c48911c24097b86932c229fa874359eSam Judd    private final boolean assertBackgroundThread;
46e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd    private final Waiter waiter;
474f7c51ca4c48911c24097b86932c229fa874359eSam Judd
484f7c51ca4c48911c24097b86932c229fa874359eSam Judd    private R resource;
494f7c51ca4c48911c24097b86932c229fa874359eSam Judd    private Request request;
504f7c51ca4c48911c24097b86932c229fa874359eSam Judd    private boolean isCancelled;
514f7c51ca4c48911c24097b86932c229fa874359eSam Judd    private Exception exception;
524f7c51ca4c48911c24097b86932c229fa874359eSam Judd    private boolean resultReceived;
53ad67eab60aed16b0269d33eb9b02eeb9f07210ebSam Judd    private boolean exceptionReceived;
544f7c51ca4c48911c24097b86932c229fa874359eSam Judd
555f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd    /**
565f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     * Constructor for a RequestFutureTarget. Should not be used directly.
575f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     */
584f7c51ca4c48911c24097b86932c229fa874359eSam Judd    public RequestFutureTarget(Handler mainHandler, int width, int height) {
59e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd        this(mainHandler, width, height, true, DEFAULT_WAITER);
604f7c51ca4c48911c24097b86932c229fa874359eSam Judd    }
614f7c51ca4c48911c24097b86932c229fa874359eSam Judd
62e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd    RequestFutureTarget(Handler mainHandler, int width, int height, boolean assertBackgroundThread, Waiter waiter) {
634f7c51ca4c48911c24097b86932c229fa874359eSam Judd        this.mainHandler = mainHandler;
644f7c51ca4c48911c24097b86932c229fa874359eSam Judd        this.width = width;
654f7c51ca4c48911c24097b86932c229fa874359eSam Judd        this.height = height;
664f7c51ca4c48911c24097b86932c229fa874359eSam Judd        this.assertBackgroundThread = assertBackgroundThread;
67e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd        this.waiter = waiter;
684f7c51ca4c48911c24097b86932c229fa874359eSam Judd    }
694f7c51ca4c48911c24097b86932c229fa874359eSam Judd
705f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd    /**
715f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     * {@inheritDoc}
725f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     */
734f7c51ca4c48911c24097b86932c229fa874359eSam Judd    @Override
744f7c51ca4c48911c24097b86932c229fa874359eSam Judd    public synchronized boolean cancel(boolean b) {
754f7c51ca4c48911c24097b86932c229fa874359eSam Judd        if (isCancelled) {
764f7c51ca4c48911c24097b86932c229fa874359eSam Judd            return true;
774f7c51ca4c48911c24097b86932c229fa874359eSam Judd        }
784f7c51ca4c48911c24097b86932c229fa874359eSam Judd
794f7c51ca4c48911c24097b86932c229fa874359eSam Judd        final boolean result = !isDone();
804f7c51ca4c48911c24097b86932c229fa874359eSam Judd        if (result) {
814f7c51ca4c48911c24097b86932c229fa874359eSam Judd            isCancelled = true;
824f7c51ca4c48911c24097b86932c229fa874359eSam Judd            clear();
83e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd            waiter.notifyAll(this);
844f7c51ca4c48911c24097b86932c229fa874359eSam Judd        }
854f7c51ca4c48911c24097b86932c229fa874359eSam Judd        return result;
864f7c51ca4c48911c24097b86932c229fa874359eSam Judd    }
874f7c51ca4c48911c24097b86932c229fa874359eSam Judd
885f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd    /**
895f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     * {@inheritDoc}
905f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     */
914f7c51ca4c48911c24097b86932c229fa874359eSam Judd    @Override
924f7c51ca4c48911c24097b86932c229fa874359eSam Judd    public synchronized boolean isCancelled() {
934f7c51ca4c48911c24097b86932c229fa874359eSam Judd        return isCancelled;
944f7c51ca4c48911c24097b86932c229fa874359eSam Judd    }
954f7c51ca4c48911c24097b86932c229fa874359eSam Judd
965f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd    /**
975f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     * {@inheritDoc}
985f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     */
994f7c51ca4c48911c24097b86932c229fa874359eSam Judd    @Override
1004f7c51ca4c48911c24097b86932c229fa874359eSam Judd    public synchronized boolean isDone() {
1014f7c51ca4c48911c24097b86932c229fa874359eSam Judd        return isCancelled || resultReceived;
1024f7c51ca4c48911c24097b86932c229fa874359eSam Judd    }
1034f7c51ca4c48911c24097b86932c229fa874359eSam Judd
1045f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd    /**
1055f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     * {@inheritDoc}
1065f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     */
1074f7c51ca4c48911c24097b86932c229fa874359eSam Judd    @Override
1084f7c51ca4c48911c24097b86932c229fa874359eSam Judd    public R get() throws InterruptedException, ExecutionException {
1094f7c51ca4c48911c24097b86932c229fa874359eSam Judd        try {
1104f7c51ca4c48911c24097b86932c229fa874359eSam Judd            return doGet(null);
1114f7c51ca4c48911c24097b86932c229fa874359eSam Judd        } catch (TimeoutException e) {
1124f7c51ca4c48911c24097b86932c229fa874359eSam Judd            throw new AssertionError(e);
1134f7c51ca4c48911c24097b86932c229fa874359eSam Judd        }
1144f7c51ca4c48911c24097b86932c229fa874359eSam Judd    }
1154f7c51ca4c48911c24097b86932c229fa874359eSam Judd
1165f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd    /**
1175f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     * {@inheritDoc}
1185f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     */
1194f7c51ca4c48911c24097b86932c229fa874359eSam Judd    @Override
1204f7c51ca4c48911c24097b86932c229fa874359eSam Judd    public R get(long time, TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException {
1214f7c51ca4c48911c24097b86932c229fa874359eSam Judd        return doGet(timeUnit.toMillis(time));
1224f7c51ca4c48911c24097b86932c229fa874359eSam Judd    }
1234f7c51ca4c48911c24097b86932c229fa874359eSam Judd
1245f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd    /**
1255f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     * A callback that should never be invoked directly.
1265f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     */
1274f7c51ca4c48911c24097b86932c229fa874359eSam Judd    @Override
1284f7c51ca4c48911c24097b86932c229fa874359eSam Judd    public void getSize(SizeReadyCallback cb) {
1294f7c51ca4c48911c24097b86932c229fa874359eSam Judd        cb.onSizeReady(width, height);
1304f7c51ca4c48911c24097b86932c229fa874359eSam Judd    }
1314f7c51ca4c48911c24097b86932c229fa874359eSam Judd
1325f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd    /**
1335f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     * {@inheritDoc}
1345f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     */
1354f7c51ca4c48911c24097b86932c229fa874359eSam Judd    @Override
1364f7c51ca4c48911c24097b86932c229fa874359eSam Judd    public void setRequest(Request request) {
1374f7c51ca4c48911c24097b86932c229fa874359eSam Judd        this.request = request;
1384f7c51ca4c48911c24097b86932c229fa874359eSam Judd    }
1394f7c51ca4c48911c24097b86932c229fa874359eSam Judd
1405f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd    /**
1415f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     * {@inheritDoc}
1425f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     */
1434f7c51ca4c48911c24097b86932c229fa874359eSam Judd    @Override
1444f7c51ca4c48911c24097b86932c229fa874359eSam Judd    public Request getRequest() {
1454f7c51ca4c48911c24097b86932c229fa874359eSam Judd        return request;
1464f7c51ca4c48911c24097b86932c229fa874359eSam Judd    }
1474f7c51ca4c48911c24097b86932c229fa874359eSam Judd
1485f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd    /**
1495f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     * A callback that should never be invoked directly.
1505f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     */
1514f7c51ca4c48911c24097b86932c229fa874359eSam Judd    @Override
152e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd    public void onLoadCleared(Drawable placeholder) {
1534f7c51ca4c48911c24097b86932c229fa874359eSam Judd        // Do nothing.
1544f7c51ca4c48911c24097b86932c229fa874359eSam Judd    }
1554f7c51ca4c48911c24097b86932c229fa874359eSam Judd
1565f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd    /**
1575f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     * A callback that should never be invoked directly.
1585f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     */
1594f7c51ca4c48911c24097b86932c229fa874359eSam Judd    @Override
160e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd    public void onLoadStarted(Drawable placeholder) {
1614f7c51ca4c48911c24097b86932c229fa874359eSam Judd        // Do nothing.
1624f7c51ca4c48911c24097b86932c229fa874359eSam Judd    }
1634f7c51ca4c48911c24097b86932c229fa874359eSam Judd
164e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd    /**
165e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd     * A callback that should never be invoked directly.
166e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd     */
167e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd    @Override
168e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd    public synchronized void onLoadFailed(Exception e, Drawable errorDrawable) {
169e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd         // We might get a null exception.
170e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd        exceptionReceived = true;
171e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd        this.exception = e;
172e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd        waiter.notifyAll(this);
173e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd    }
174e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd
175e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd    /**
176e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd     * A callback that should never be invoked directly.
177e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd     */
178e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd    @Override
1795c3697fff7866246e107030b8c92359d4ebc1cf3Sam Judd    public synchronized void onResourceReady(R resource, GlideAnimation<? super R> glideAnimation) {
180e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd        // We might get a null result.
181e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd        resultReceived = true;
182e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd        this.resource = resource;
183e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd        waiter.notifyAll(this);
184e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd    }
185e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd
1864f7c51ca4c48911c24097b86932c229fa874359eSam Judd    private synchronized R doGet(Long timeoutMillis) throws ExecutionException, InterruptedException, TimeoutException {
1874f7c51ca4c48911c24097b86932c229fa874359eSam Judd        if (assertBackgroundThread) {
1884f7c51ca4c48911c24097b86932c229fa874359eSam Judd            Util.assertBackgroundThread();
1894f7c51ca4c48911c24097b86932c229fa874359eSam Judd        }
1904f7c51ca4c48911c24097b86932c229fa874359eSam Judd
1914f7c51ca4c48911c24097b86932c229fa874359eSam Judd        if (isCancelled) {
1924f7c51ca4c48911c24097b86932c229fa874359eSam Judd            throw new CancellationException();
193ad67eab60aed16b0269d33eb9b02eeb9f07210ebSam Judd        } else if (exceptionReceived) {
1944f7c51ca4c48911c24097b86932c229fa874359eSam Judd            throw new ExecutionException(exception);
1954f7c51ca4c48911c24097b86932c229fa874359eSam Judd        } else if (resultReceived) {
1964f7c51ca4c48911c24097b86932c229fa874359eSam Judd            return resource;
1974f7c51ca4c48911c24097b86932c229fa874359eSam Judd        }
1984f7c51ca4c48911c24097b86932c229fa874359eSam Judd
1994f7c51ca4c48911c24097b86932c229fa874359eSam Judd        if (timeoutMillis == null) {
200e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd            waiter.waitForTimeout(this, 0);
201ad67eab60aed16b0269d33eb9b02eeb9f07210ebSam Judd        } else if (timeoutMillis > 0) {
202e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd            waiter.waitForTimeout(this, timeoutMillis);
2034f7c51ca4c48911c24097b86932c229fa874359eSam Judd        }
2044f7c51ca4c48911c24097b86932c229fa874359eSam Judd
20518d5c371d568d0f2e33b8b5e78b400156c1720f5Sam Judd        if (Thread.interrupted()) {
20618d5c371d568d0f2e33b8b5e78b400156c1720f5Sam Judd            throw new InterruptedException();
207ad67eab60aed16b0269d33eb9b02eeb9f07210ebSam Judd        } else if (exceptionReceived) {
2084f7c51ca4c48911c24097b86932c229fa874359eSam Judd            throw new ExecutionException(exception);
2094f7c51ca4c48911c24097b86932c229fa874359eSam Judd        } else if (isCancelled) {
2104f7c51ca4c48911c24097b86932c229fa874359eSam Judd            throw new CancellationException();
2114f7c51ca4c48911c24097b86932c229fa874359eSam Judd        } else if (!resultReceived) {
2124f7c51ca4c48911c24097b86932c229fa874359eSam Judd            throw new TimeoutException();
2134f7c51ca4c48911c24097b86932c229fa874359eSam Judd        }
2144f7c51ca4c48911c24097b86932c229fa874359eSam Judd
2154f7c51ca4c48911c24097b86932c229fa874359eSam Judd        return resource;
2164f7c51ca4c48911c24097b86932c229fa874359eSam Judd    }
2174f7c51ca4c48911c24097b86932c229fa874359eSam Judd
2185f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd    /**
2195f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     * A callback that should never be invoked directly.
2205f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     */
2214f7c51ca4c48911c24097b86932c229fa874359eSam Judd    @Override
2224f7c51ca4c48911c24097b86932c229fa874359eSam Judd    public void run() {
2234f7c51ca4c48911c24097b86932c229fa874359eSam Judd        request.clear();
2244f7c51ca4c48911c24097b86932c229fa874359eSam Judd    }
2254f7c51ca4c48911c24097b86932c229fa874359eSam Judd
2265f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd    /**
2275f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     * Can be safely called from either the main thread or a background thread to cleanup the resources used by this
2285f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     * target.
2295f4610b54d517be58105bcf73ce3291ba79f9f40Sam Judd     */
2304f7c51ca4c48911c24097b86932c229fa874359eSam Judd    @Override
2314f7c51ca4c48911c24097b86932c229fa874359eSam Judd    public void clear() {
2324f7c51ca4c48911c24097b86932c229fa874359eSam Judd        mainHandler.post(this);
2334f7c51ca4c48911c24097b86932c229fa874359eSam Judd    }
234e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd
235d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd    /**
236d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd     * {@inheritDoc}
237d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd     */
238d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd    @Override
239d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd    public void onStart() {
240d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd        // Do nothing.
241d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd    }
242d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd
243d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd    /**
244d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd     * {@inheritDoc}
245d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd     */
246d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd    @Override
247d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd    public void onStop() {
248d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd        // Do nothing.
249d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd    }
250d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd
251d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd    /**
252d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd     * {@inheritDoc}
253d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd     */
254d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd    @Override
255d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd    public void onDestroy() {
256d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd        // Do nothing.
257d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd    }
258d8eac4cec0fe1fa9b496998cfac858fd603f4f32Sam Judd
2595ba19a0e69ad3a651b8f13ba45de48a56b56ce36Sam Judd    // Visible for testing.
2605ba19a0e69ad3a651b8f13ba45de48a56b56ce36Sam Judd    static class Waiter {
261e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd
262e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd        public void waitForTimeout(Object toWaitOn, long timeoutMillis) throws InterruptedException {
263e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd            toWaitOn.wait(timeoutMillis);
264e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd        }
265e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd
266e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd        public void notifyAll(Object toNotify) {
267e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd            toNotify.notifyAll();
268e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd        }
269e9234a91ace35d1225d9ead0c1b47320ea541fcfSam Judd    }
2704f7c51ca4c48911c24097b86932c229fa874359eSam Judd}
271