Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d27721f4 authored by Atneya Nair's avatar Atneya Nair
Browse files

Add filtering over action collection to test util

The getFutureForIntent utils currently filter on a single action, but
often we want to listen for multiple actions.

Add a version which takes a collection of actions, completing if the
predicate succeeds following any of the actions being received.

Flag: TEST_ONLY
Test: atest CtsAudioRecordPermissionTests
Bug: 349468644
Change-Id: I13d7b60f373897413316b6b96564e0c0c75236d1
parent 91277279
Loading
Loading
Loading
Loading
+68 −9
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;

import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -35,12 +36,13 @@ import java.util.function.Predicate;
/** Utils for audio tests. */
public class TestUtils {
    /**
     * Return a future for an intent delivered by a broadcast receiver which matches an
     * action and predicate.
     * Return a future for an intent delivered by a broadcast receiver which matches an action and
     * predicate.
     *
     * @param context - Context to register the receiver with
     * @param action - String representing action to register receiver for
     * @param pred - Predicate which sets the future if evaluates to true, otherwise, leaves
     * the future unset. If the predicate throws, the future is set exceptionally
     * @param pred - Predicate which sets the future if evaluates to true, otherwise, leaves the
     *     future unset. If the predicate throws, the future is set exceptionally
     * @return - The future representing intent delivery matching predicate.
     */
    public static ListenableFuture<Intent> getFutureForIntent(
@@ -76,17 +78,74 @@ public class TestUtils {
    }

    /**
     * Same as previous, but with no predicate.
     * Return a future for an intent delivered by a broadcast receiver which matches one of a set of
     * actions and predicate.
     *
     * @param context - Context to register the receiver with
     * @param actionsCollection - Collection of actions which to listen for, completing on any
     * @param pred - Predicate which sets the future if evaluates to true, otherwise, leaves the
     *     future unset. If the predicate throws, the future is set exceptionally
     * @return - The future representing intent delivery matching predicate.
     */
    public static ListenableFuture<Intent> getFutureForIntent(
            Context context, Collection<String> actionsCollection, Predicate<Intent> pred) {
        // These are evaluated async
        Objects.requireNonNull(actionsCollection);
        Objects.requireNonNull(pred);
        if (actionsCollection.isEmpty()) {
            throw new IllegalArgumentException("actionsCollection must not be empty");
        }
        return getFutureForListener(
                (recv) ->
                        context.registerReceiver(
                                recv,
                                actionsCollection.stream()
                                        .reduce(
                                                new IntentFilter(),
                                                (IntentFilter filter, String x) -> {
                                                    filter.addAction(x);
                                                    return filter;
                                                },
                                                (x, y) -> {
                                                    throw new IllegalStateException(
                                                            "No parallel support");
                                                }),
                                Context.RECEIVER_EXPORTED),
                (recv) -> {
                    try {
                        context.unregisterReceiver(recv);
                    } catch (IllegalArgumentException e) {
                        // Thrown when receiver is already unregistered, nothing to do
                    }
                },
                (completer) ->
                        new BroadcastReceiver() {
                            @Override
                            public void onReceive(Context context, Intent intent) {
                                try {
                                    if (actionsCollection.contains(intent.getAction())
                                            && pred.test(intent)) {
                                        completer.set(intent);
                                    }
                                } catch (Exception e) {
                                    completer.setException(e);
                                }
                            }
                        },
                "Intent receiver future for actions: " + actionsCollection);
    }

    /** Same as previous, but with no predicate. */
    public static ListenableFuture<Intent> getFutureForIntent(Context context, String action) {
        return getFutureForIntent(context, action, i -> true);
    }

    /**
     * Return a future for a callback registered to a listener interface.
     *
     * @param registerFunc - Function which consumes the callback object for registration
     * @param unregisterFunc - Function which consumes the callback object for unregistration
     * This function is called when the future is completed or cancelled
     * @param unregisterFunc - Function which consumes the callback object for unregistration This
     *     function is called when the future is completed or cancelled
     * @param instantiateCallback - Factory function for the callback object, provided a completer
     *     object (see {@code CallbackToFutureAdapter.Completer<T>}), which is a logical reference
     *     to the future returned by this function