blob: 1ff57691ecdb44c4ed1bb13dbf6ebcd73623b1f7 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.feed;
import com.google.android.libraries.feed.common.functional.Consumer;
import org.junit.Assert;
import org.chromium.base.task.PostTask;
import org.chromium.content_public.browser.UiThreadTaskTraits;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
/**
* ConsumerSyncWrapper allows the user to wait for the wrapped consumer to
* accept an input.
*/
class ConsumerSyncWrapper<T> implements Consumer<T> {
private final Consumer<T> mWrapped;
private final AtomicReference<T> mResult;
private final CountDownLatch mLatch;
private ConsumerSyncWrapper(Consumer<T> wrappedConsumer) {
mWrapped = wrappedConsumer;
mResult = new AtomicReference<>();
mLatch = new CountDownLatch(1);
}
private void blockAndWrappedAccept(long timeoutMs) {
try {
mLatch.await(timeoutMs, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Assert.fail("waitForAccept was interrupted: " + e.getMessage());
}
mWrapped.accept(mResult.get());
}
@Override
public void accept(T input) {
mResult.set(input);
mLatch.countDown();
}
/**
* waitForConsumer calls the consumer operation on the UI Thread then blocks until the
* consumer has accepted the results of the operation.
*
* @param consumer The {@link Consumer} to block on.
* @param operation The operation that should feed its result to the consumer.
* @param timeoutMs The timeout in milliseconds to wait for operation to execute
*/
static public <T> void waitForConsumer(
Consumer<T> consumer, Consumer<Consumer<T>> operation, long timeoutMs) {
ConsumerSyncWrapper<T> wrapper = new ConsumerSyncWrapper<>(consumer);
PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> operation.accept(wrapper));
wrapper.blockAndWrappedAccept(timeoutMs);
}
}