CallbackHelper.java revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5package org.chromium.content.browser.test.util; 6 7import java.util.concurrent.TimeUnit; 8import java.util.concurrent.TimeoutException; 9 10/** 11 * A helper class for listening to callbacks. 12 */ 13public class CallbackHelper { 14 protected static int WAIT_TIMEOUT_SECONDS = 5; 15 16 private final Object mLock = new Object(); 17 protected int mCallCount = 0; 18 19 /** 20 * Gets the number of times the callback has been called. 21 * 22 * The call count can be used with the waitForCallback() method, indicating a point 23 * in time after which the caller wishes to record calls to the callback. 24 * 25 * In order to wait for a callback caused by X, the call count should be obtained 26 * before X occurs. 27 * 28 * NOTE: any call to the callback that occurs after the call count is obtained 29 * will result in the corresponding wait call to resume execution. The call count 30 * is intended to 'catch' callbacks that occur after X but before waitForCallback() 31 * is called. 32 */ 33 public int getCallCount() { 34 synchronized(mLock) { 35 return mCallCount; 36 } 37 } 38 39 /** 40 * Blocks until the callback is called the specified number of 41 * times or throws an exception if we exceeded the specified time frame. 42 * 43 * This will wait for a callback to be called a specified number of times after 44 * the point in time at which the call count was obtained. The method will return 45 * immediately if a call occurred the specified number of times after the 46 * call count was obtained but before the method was called, otherwise the method will 47 * block until the specified call count is reached. 48 * 49 * @param currentCallCount the value obtained by calling getCallCount(). 50 * @param numberOfCallsToWaitFor number of calls (counting since 51 * currentCallCount was obtained) that we will wait for. 52 * @param timeout timeout value. We will wait the specified amount of time for a single 53 * callback to occur so the method call may block up to 54 * <code>numberOfCallsToWaitFor * timeout</code> units. 55 * @param unit timeout unit. 56 * @throws InterruptedException 57 * @throws TimeoutException Thrown if the method times out before onPageFinished is called. 58 */ 59 public void waitForCallback(int currentCallCount, int numberOfCallsToWaitFor, long timeout, 60 TimeUnit unit) throws InterruptedException, TimeoutException { 61 assert mCallCount >= currentCallCount; 62 assert numberOfCallsToWaitFor > 0; 63 synchronized(mLock) { 64 int callCountWhenDoneWaiting = currentCallCount + numberOfCallsToWaitFor; 65 while (callCountWhenDoneWaiting > mCallCount) { 66 int callCountBeforeWait = mCallCount; 67 mLock.wait(unit.toMillis(timeout)); 68 if (callCountBeforeWait == mCallCount) { 69 throw new TimeoutException("waitForCallback timed out!"); 70 } 71 } 72 } 73 } 74 75 public void waitForCallback(int currentCallCount, int numberOfCallsToWaitFor) 76 throws InterruptedException, TimeoutException { 77 waitForCallback(currentCallCount, numberOfCallsToWaitFor, 78 WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS); 79 } 80 81 public void waitForCallback(int currentCallCount) 82 throws InterruptedException, TimeoutException { 83 waitForCallback(currentCallCount, 1); 84 } 85 86 /** 87 * Should be called when the callback associated with this helper object is called. 88 */ 89 public void notifyCalled() { 90 synchronized(mLock) { 91 mCallCount++; 92 mLock.notifyAll(); 93 } 94 } 95} 96