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