mirror of
https://github.com/androidx/media.git
synced 2025-05-07 15:40:37 +08:00
Replace MutableFlags by immutable class
PiperOrigin-RevId: 362043183
This commit is contained in:
parent
851c915e38
commit
4a6859e5e2
@ -95,7 +95,7 @@ public final class CastPlayer extends BasePlayer {
|
||||
private final SeekResultCallback seekResultCallback;
|
||||
|
||||
// Listeners and notification.
|
||||
private final ListenerSet<Player.EventListener, Player.Events> listeners;
|
||||
private final ListenerSet<Player.EventListener> listeners;
|
||||
@Nullable private SessionAvailabilityListener sessionAvailabilityListener;
|
||||
|
||||
// Internal state.
|
||||
@ -139,8 +139,7 @@ public final class CastPlayer extends BasePlayer {
|
||||
new ListenerSet<>(
|
||||
Looper.getMainLooper(),
|
||||
Clock.DEFAULT,
|
||||
Player.Events::new,
|
||||
(listener, eventFlags) -> listener.onEvents(/* player= */ this, eventFlags));
|
||||
(listener, flags) -> listener.onEvents(/* player= */ this, new Events(flags)));
|
||||
|
||||
playWhenReady = new StateHolder<>(false);
|
||||
repeatMode = new StateHolder<>(REPEAT_MODE_OFF);
|
||||
|
@ -27,7 +27,7 @@ import com.google.android.exoplayer2.util.ListenerSet;
|
||||
/** A fake player for testing content/ad playback. */
|
||||
/* package */ final class FakePlayer extends StubExoPlayer {
|
||||
|
||||
private final ListenerSet<EventListener, Events> listeners;
|
||||
private final ListenerSet<EventListener> listeners;
|
||||
private final Timeline.Period period;
|
||||
|
||||
private Timeline timeline;
|
||||
@ -45,8 +45,7 @@ import com.google.android.exoplayer2.util.ListenerSet;
|
||||
new ListenerSet<>(
|
||||
Looper.getMainLooper(),
|
||||
Clock.DEFAULT,
|
||||
Player.Events::new,
|
||||
(listener, eventFlags) -> listener.onEvents(/* player= */ this, eventFlags));
|
||||
(listener, flags) -> listener.onEvents(/* player= */ this, new Events(flags)));
|
||||
period = new Timeline.Period();
|
||||
state = Player.STATE_IDLE;
|
||||
playWhenReady = true;
|
||||
|
@ -15,11 +15,9 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2;
|
||||
|
||||
import static com.google.android.exoplayer2.util.Assertions.checkState;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
@ -37,7 +35,7 @@ import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.text.Cue;
|
||||
import com.google.android.exoplayer2.text.TextOutput;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.util.MutableFlags;
|
||||
import com.google.android.exoplayer2.util.ExoFlags;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
|
||||
import com.google.android.exoplayer2.video.VideoListener;
|
||||
@ -664,17 +662,27 @@ public interface Player {
|
||||
}
|
||||
|
||||
/** A set of {@link EventFlags}. */
|
||||
final class Events extends MutableFlags {
|
||||
final class Events {
|
||||
|
||||
private final ExoFlags flags;
|
||||
|
||||
/**
|
||||
* Creates an instance.
|
||||
*
|
||||
* @param flags The {@link ExoFlags} containing the {@link EventFlags} in the set.
|
||||
*/
|
||||
public Events(ExoFlags flags) {
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given event occurred.
|
||||
*
|
||||
* @param event The {@link EventFlags event}.
|
||||
* @return Whether the event occurred.
|
||||
*/
|
||||
@Override
|
||||
public boolean contains(@EventFlags int event) {
|
||||
// Overridden to add IntDef compiler enforcement and new JavaDoc.
|
||||
return super.contains(event);
|
||||
return flags.contains(event);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -683,10 +691,13 @@ public interface Player {
|
||||
* @param events The {@link EventFlags events}.
|
||||
* @return Whether any of the events occurred.
|
||||
*/
|
||||
@Override
|
||||
public boolean containsAny(@EventFlags int... events) {
|
||||
// Overridden to add IntDef compiler enforcement and new JavaDoc.
|
||||
return super.containsAny(events);
|
||||
return flags.containsAny(events);
|
||||
}
|
||||
|
||||
/** Returns the number of events in the set. */
|
||||
public int size() {
|
||||
return flags.size();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -698,11 +709,9 @@ public interface Player {
|
||||
* @param index The index. Must be between 0 (inclusive) and {@link #size()} (exclusive).
|
||||
* @return The {@link EventFlags event} at the given index.
|
||||
*/
|
||||
@Override
|
||||
@EventFlags
|
||||
public int get(int index) {
|
||||
// Overridden to add IntDef compiler enforcement and new JavaDoc.
|
||||
return super.get(index);
|
||||
return flags.get(index);
|
||||
}
|
||||
}
|
||||
|
||||
@ -716,18 +725,11 @@ public interface Player {
|
||||
/** A builder for {@link Commands} instances. */
|
||||
public static final class Builder {
|
||||
|
||||
private final SparseBooleanArray commandsArray;
|
||||
|
||||
private boolean buildCalled;
|
||||
private final ExoFlags.Builder flagsBuilder;
|
||||
|
||||
/** Creates a builder. */
|
||||
public Builder() {
|
||||
commandsArray = new SparseBooleanArray();
|
||||
}
|
||||
|
||||
/** Creates a builder with the values of the provided {@link Commands}. */
|
||||
private Builder(Commands commands) {
|
||||
this.commandsArray = commands.commandsArray.clone();
|
||||
flagsBuilder = new ExoFlags.Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -738,8 +740,7 @@ public interface Player {
|
||||
* @throws IllegalStateException If {@link #build()} has already been called.
|
||||
*/
|
||||
public Builder add(@Command int command) {
|
||||
checkState(!buildCalled);
|
||||
commandsArray.append(command, /* value= */ true);
|
||||
flagsBuilder.add(command);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -752,39 +753,32 @@ public interface Player {
|
||||
* @throws IllegalStateException If {@link #build()} has already been called.
|
||||
*/
|
||||
public Builder addIf(@Command int command, boolean condition) {
|
||||
checkState(!buildCalled);
|
||||
if (condition) {
|
||||
commandsArray.append(command, /* value= */ true);
|
||||
}
|
||||
flagsBuilder.addIf(command, condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds a {@link Commands} instance. */
|
||||
/**
|
||||
* Builds a {@link Commands} instance.
|
||||
*
|
||||
* @throws IllegalStateException If this method has already been called.
|
||||
*/
|
||||
public Commands build() {
|
||||
checkState(!buildCalled);
|
||||
buildCalled = true;
|
||||
return new Commands(commandsArray);
|
||||
return new Commands(flagsBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
/** An empty set of commands. */
|
||||
public static final Commands EMPTY = new Commands.Builder().build();
|
||||
public static final Commands EMPTY = new Builder().build();
|
||||
|
||||
// A SparseBooleanArray is used instead of a Set to avoid auto-boxing the Command values.
|
||||
private final SparseBooleanArray commandsArray;
|
||||
private final ExoFlags flags;
|
||||
|
||||
private Commands(SparseBooleanArray commandsArray) {
|
||||
this.commandsArray = commandsArray;
|
||||
}
|
||||
|
||||
/** Returns a {@link Commands.Builder} initialized with the values of this instance. */
|
||||
public Builder buildUpon() {
|
||||
return new Builder(this);
|
||||
private Commands(ExoFlags flags) {
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
/** Returns whether the set of commands contains the specified {@link Command}. */
|
||||
public boolean contains(@Command int command) {
|
||||
return commandsArray.get(command);
|
||||
return flags.contains(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -796,12 +790,12 @@ public interface Player {
|
||||
return false;
|
||||
}
|
||||
Commands commands = (Commands) obj;
|
||||
return this.commandsArray.equals(commands.commandsArray);
|
||||
return flags.equals(commands.flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return commandsArray.hashCode();
|
||||
return flags.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.util;
|
||||
|
||||
import static com.google.android.exoplayer2.util.Assertions.checkState;
|
||||
|
||||
import android.util.SparseBooleanArray;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@ -23,28 +25,68 @@ import androidx.annotation.Nullable;
|
||||
*
|
||||
* <p>Intended for usages where the number of flags may exceed 32 and can no longer be represented
|
||||
* by an IntDef.
|
||||
*
|
||||
* <p>Instances are immutable.
|
||||
*/
|
||||
public class MutableFlags {
|
||||
public final class ExoFlags {
|
||||
|
||||
/** A builder for {@link ExoFlags} instances. */
|
||||
public static final class Builder {
|
||||
|
||||
private final SparseBooleanArray flags;
|
||||
|
||||
private boolean buildCalled;
|
||||
|
||||
/** Creates a builder. */
|
||||
public Builder() {
|
||||
flags = new SparseBooleanArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a flag.
|
||||
*
|
||||
* @param flag A flag.
|
||||
* @return This builder.
|
||||
* @throws IllegalStateException If {@link #build()} has already been called.
|
||||
*/
|
||||
public Builder add(int flag) {
|
||||
checkState(!buildCalled);
|
||||
flags.append(flag, /* value= */ true);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a flag if the provided condition is true. Does nothing otherwise.
|
||||
*
|
||||
* @param flag A flag.
|
||||
* @param condition A condition.
|
||||
* @return This builder.
|
||||
* @throws IllegalStateException If {@link #build()} has already been called.
|
||||
*/
|
||||
public Builder addIf(int flag, boolean condition) {
|
||||
if (condition) {
|
||||
return add(flag);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an {@link ExoFlags} instance.
|
||||
*
|
||||
* @throws IllegalStateException If this method has already been called.
|
||||
*/
|
||||
public ExoFlags build() {
|
||||
checkState(!buildCalled);
|
||||
buildCalled = true;
|
||||
return new ExoFlags(flags);
|
||||
}
|
||||
}
|
||||
|
||||
// A SparseBooleanArray is used instead of a Set to avoid auto-boxing the flag values.
|
||||
private final SparseBooleanArray flags;
|
||||
|
||||
/** Creates the set of flags. */
|
||||
public MutableFlags() {
|
||||
flags = new SparseBooleanArray();
|
||||
}
|
||||
|
||||
/** Clears all previously set flags. */
|
||||
public void clear() {
|
||||
flags.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a flag to the set.
|
||||
*
|
||||
* @param flag The flag to add.
|
||||
*/
|
||||
public void add(int flag) {
|
||||
flags.append(flag, /* value= */ true);
|
||||
private ExoFlags(SparseBooleanArray flags) {
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,10 +136,10 @@ public class MutableFlags {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof MutableFlags)) {
|
||||
if (!(o instanceof ExoFlags)) {
|
||||
return false;
|
||||
}
|
||||
MutableFlags that = (MutableFlags) o;
|
||||
ExoFlags that = (ExoFlags) o;
|
||||
return flags.equals(that.flags);
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ import android.os.Message;
|
||||
import androidx.annotation.CheckResult;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.common.base.Supplier;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import javax.annotation.Nonnull;
|
||||
@ -35,9 +34,8 @@ import javax.annotation.Nonnull;
|
||||
* was enqueued and haven't been removed since.
|
||||
*
|
||||
* @param <T> The listener type.
|
||||
* @param <E> The {@link MutableFlags} type used to indicate which events occurred.
|
||||
*/
|
||||
public final class ListenerSet<T, E extends MutableFlags> {
|
||||
public final class ListenerSet<T> {
|
||||
|
||||
/**
|
||||
* An event sent to a listener.
|
||||
@ -55,17 +53,17 @@ public final class ListenerSet<T, E extends MutableFlags> {
|
||||
* iteration were handled by the listener.
|
||||
*
|
||||
* @param <T> The listener type.
|
||||
* @param <E> The {@link MutableFlags} type used to indicate which events occurred.
|
||||
*/
|
||||
public interface IterationFinishedEvent<T, E extends MutableFlags> {
|
||||
public interface IterationFinishedEvent<T> {
|
||||
|
||||
/**
|
||||
* Invokes the iteration finished event.
|
||||
*
|
||||
* @param listener The listener to invoke the event on.
|
||||
* @param eventFlags The combined event flags of all events sent in this iteration.
|
||||
* @param eventFlags The combined event {@link ExoFlags flags} of all events sent in this
|
||||
* iteration.
|
||||
*/
|
||||
void invoke(T listener, E eventFlags);
|
||||
void invoke(T listener, ExoFlags eventFlags);
|
||||
}
|
||||
|
||||
private static final int MSG_ITERATION_FINISHED = 0;
|
||||
@ -73,9 +71,8 @@ public final class ListenerSet<T, E extends MutableFlags> {
|
||||
|
||||
private final Clock clock;
|
||||
private final HandlerWrapper handler;
|
||||
private final Supplier<E> eventFlagsSupplier;
|
||||
private final IterationFinishedEvent<T, E> iterationFinishedEvent;
|
||||
private final CopyOnWriteArraySet<ListenerHolder<T, E>> listeners;
|
||||
private final IterationFinishedEvent<T> iterationFinishedEvent;
|
||||
private final CopyOnWriteArraySet<ListenerHolder<T>> listeners;
|
||||
private final ArrayDeque<Runnable> flushingEvents;
|
||||
private final ArrayDeque<Runnable> queuedEvents;
|
||||
|
||||
@ -87,33 +84,24 @@ public final class ListenerSet<T, E extends MutableFlags> {
|
||||
* @param looper A {@link Looper} used to call listeners on. The same {@link Looper} must be used
|
||||
* to call all other methods of this class.
|
||||
* @param clock A {@link Clock}.
|
||||
* @param eventFlagsSupplier A {@link Supplier} for new instances of {@link E the event flags
|
||||
* type}.
|
||||
* @param iterationFinishedEvent An {@link IterationFinishedEvent} sent when all other events sent
|
||||
* during one {@link Looper} message queue iteration were handled by the listeners.
|
||||
*/
|
||||
public ListenerSet(
|
||||
Looper looper,
|
||||
Clock clock,
|
||||
Supplier<E> eventFlagsSupplier,
|
||||
IterationFinishedEvent<T, E> iterationFinishedEvent) {
|
||||
public ListenerSet(Looper looper, Clock clock, IterationFinishedEvent<T> iterationFinishedEvent) {
|
||||
this(
|
||||
/* listeners= */ new CopyOnWriteArraySet<>(),
|
||||
looper,
|
||||
clock,
|
||||
eventFlagsSupplier,
|
||||
iterationFinishedEvent);
|
||||
}
|
||||
|
||||
private ListenerSet(
|
||||
CopyOnWriteArraySet<ListenerHolder<T, E>> listeners,
|
||||
CopyOnWriteArraySet<ListenerHolder<T>> listeners,
|
||||
Looper looper,
|
||||
Clock clock,
|
||||
Supplier<E> eventFlagsSupplier,
|
||||
IterationFinishedEvent<T, E> iterationFinishedEvent) {
|
||||
IterationFinishedEvent<T> iterationFinishedEvent) {
|
||||
this.clock = clock;
|
||||
this.listeners = listeners;
|
||||
this.eventFlagsSupplier = eventFlagsSupplier;
|
||||
this.iterationFinishedEvent = iterationFinishedEvent;
|
||||
flushingEvents = new ArrayDeque<>();
|
||||
queuedEvents = new ArrayDeque<>();
|
||||
@ -132,9 +120,8 @@ public final class ListenerSet<T, E extends MutableFlags> {
|
||||
* @return The copied listener set.
|
||||
*/
|
||||
@CheckResult
|
||||
public ListenerSet<T, E> copy(
|
||||
Looper looper, IterationFinishedEvent<T, E> iterationFinishedEvent) {
|
||||
return new ListenerSet<>(listeners, looper, clock, eventFlagsSupplier, iterationFinishedEvent);
|
||||
public ListenerSet<T> copy(Looper looper, IterationFinishedEvent<T> iterationFinishedEvent) {
|
||||
return new ListenerSet<>(listeners, looper, clock, iterationFinishedEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,7 +136,7 @@ public final class ListenerSet<T, E extends MutableFlags> {
|
||||
return;
|
||||
}
|
||||
Assertions.checkNotNull(listener);
|
||||
listeners.add(new ListenerHolder<>(listener, eventFlagsSupplier));
|
||||
listeners.add(new ListenerHolder<>(listener));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -160,7 +147,7 @@ public final class ListenerSet<T, E extends MutableFlags> {
|
||||
* @param listener The listener to be removed.
|
||||
*/
|
||||
public void remove(T listener) {
|
||||
for (ListenerHolder<T, E> listenerHolder : listeners) {
|
||||
for (ListenerHolder<T> listenerHolder : listeners) {
|
||||
if (listenerHolder.listener.equals(listener)) {
|
||||
listenerHolder.release(iterationFinishedEvent);
|
||||
listeners.remove(listenerHolder);
|
||||
@ -176,11 +163,10 @@ public final class ListenerSet<T, E extends MutableFlags> {
|
||||
* @param event The event.
|
||||
*/
|
||||
public void queueEvent(int eventFlag, Event<T> event) {
|
||||
CopyOnWriteArraySet<ListenerHolder<T, E>> listenerSnapshot =
|
||||
new CopyOnWriteArraySet<>(listeners);
|
||||
CopyOnWriteArraySet<ListenerHolder<T>> listenerSnapshot = new CopyOnWriteArraySet<>(listeners);
|
||||
queuedEvents.add(
|
||||
() -> {
|
||||
for (ListenerHolder<T, E> holder : listenerSnapshot) {
|
||||
for (ListenerHolder<T> holder : listenerSnapshot) {
|
||||
holder.invoke(eventFlag, event);
|
||||
}
|
||||
});
|
||||
@ -226,7 +212,7 @@ public final class ListenerSet<T, E extends MutableFlags> {
|
||||
* <p>This will ensure no events are sent to any listener after this method has been called.
|
||||
*/
|
||||
public void release() {
|
||||
for (ListenerHolder<T, E> listenerHolder : listeners) {
|
||||
for (ListenerHolder<T> listenerHolder : listeners) {
|
||||
listenerHolder.release(iterationFinishedEvent);
|
||||
}
|
||||
listeners.clear();
|
||||
@ -249,8 +235,8 @@ public final class ListenerSet<T, E extends MutableFlags> {
|
||||
|
||||
private boolean handleMessage(Message message) {
|
||||
if (message.what == MSG_ITERATION_FINISHED) {
|
||||
for (ListenerHolder<T, E> holder : listeners) {
|
||||
holder.iterationFinished(eventFlagsSupplier, iterationFinishedEvent);
|
||||
for (ListenerHolder<T> holder : listeners) {
|
||||
holder.iterationFinished(iterationFinishedEvent);
|
||||
if (handler.hasMessages(MSG_ITERATION_FINISHED)) {
|
||||
// The invocation above triggered new events (and thus scheduled a new message). We need
|
||||
// to stop here because this new message will take care of informing every listener about
|
||||
@ -268,45 +254,44 @@ public final class ListenerSet<T, E extends MutableFlags> {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final class ListenerHolder<T, E extends MutableFlags> {
|
||||
private static final class ListenerHolder<T> {
|
||||
|
||||
@Nonnull public final T listener;
|
||||
|
||||
private E eventsFlags;
|
||||
private ExoFlags.Builder flagsBuilder;
|
||||
private boolean needsIterationFinishedEvent;
|
||||
private boolean released;
|
||||
|
||||
public ListenerHolder(@Nonnull T listener, Supplier<E> eventFlagSupplier) {
|
||||
public ListenerHolder(@Nonnull T listener) {
|
||||
this.listener = listener;
|
||||
this.eventsFlags = eventFlagSupplier.get();
|
||||
this.flagsBuilder = new ExoFlags.Builder();
|
||||
}
|
||||
|
||||
public void release(IterationFinishedEvent<T, E> event) {
|
||||
public void release(IterationFinishedEvent<T> event) {
|
||||
released = true;
|
||||
if (needsIterationFinishedEvent) {
|
||||
event.invoke(listener, eventsFlags);
|
||||
event.invoke(listener, flagsBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
public void invoke(int eventFlag, Event<T> event) {
|
||||
if (!released) {
|
||||
if (eventFlag != C.INDEX_UNSET) {
|
||||
eventsFlags.add(eventFlag);
|
||||
flagsBuilder.add(eventFlag);
|
||||
}
|
||||
needsIterationFinishedEvent = true;
|
||||
event.invoke(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void iterationFinished(
|
||||
Supplier<E> eventFlagSupplier, IterationFinishedEvent<T, E> event) {
|
||||
public void iterationFinished(IterationFinishedEvent<T> event) {
|
||||
if (!released && needsIterationFinishedEvent) {
|
||||
// Reset flags before invoking the listener to ensure we keep all new flags that are set by
|
||||
// recursive events triggered from this callback.
|
||||
E flagToNotify = eventsFlags;
|
||||
eventsFlags = eventFlagSupplier.get();
|
||||
ExoFlags flagsToNotify = flagsBuilder.build();
|
||||
flagsBuilder = new ExoFlags.Builder();
|
||||
needsIterationFinishedEvent = false;
|
||||
event.invoke(listener, flagToNotify);
|
||||
event.invoke(listener, flagsToNotify);
|
||||
}
|
||||
}
|
||||
|
||||
@ -318,7 +303,7 @@ public final class ListenerSet<T, E extends MutableFlags> {
|
||||
if (other == null || getClass() != other.getClass()) {
|
||||
return false;
|
||||
}
|
||||
return listener.equals(((ListenerHolder<?, ?>) other).listener);
|
||||
return listener.equals(((ListenerHolder<?>) other).listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -24,13 +24,13 @@ import java.util.List;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/** Unit test for {@link MutableFlags}. */
|
||||
/** Unit test for {@link ExoFlags}. */
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public final class MutableFlagsTest {
|
||||
public final class ExoFlagsTest {
|
||||
|
||||
@Test
|
||||
public void contains_withoutAdd_returnsFalseForAllValues() {
|
||||
MutableFlags flags = new MutableFlags();
|
||||
ExoFlags flags = new ExoFlags.Builder().build();
|
||||
|
||||
assertThat(flags.contains(/* flag= */ -1234)).isFalse();
|
||||
assertThat(flags.contains(/* flag= */ 0)).isFalse();
|
||||
@ -40,12 +40,13 @@ public final class MutableFlagsTest {
|
||||
|
||||
@Test
|
||||
public void contains_afterAdd_returnsTrueForAddedValues() {
|
||||
MutableFlags flags = new MutableFlags();
|
||||
|
||||
flags.add(/* flag= */ -1234);
|
||||
flags.add(/* flag= */ 0);
|
||||
flags.add(/* flag= */ 2);
|
||||
flags.add(/* flag= */ Integer.MAX_VALUE);
|
||||
ExoFlags flags =
|
||||
new ExoFlags.Builder()
|
||||
.add(/* flag= */ -1234)
|
||||
.add(/* flag= */ 0)
|
||||
.add(/* flag= */ 2)
|
||||
.add(/* flag= */ Integer.MAX_VALUE)
|
||||
.build();
|
||||
|
||||
assertThat(flags.contains(/* flag= */ -1235)).isFalse();
|
||||
assertThat(flags.contains(/* flag= */ -1234)).isTrue();
|
||||
@ -57,79 +58,94 @@ public final class MutableFlagsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contains_afterClear_returnsFalseForAllValues() {
|
||||
MutableFlags flags = new MutableFlags();
|
||||
flags.add(/* flag= */ -1234);
|
||||
flags.add(/* flag= */ 0);
|
||||
flags.add(/* flag= */ 2);
|
||||
flags.add(/* flag= */ Integer.MAX_VALUE);
|
||||
public void contains_afterAddIf_returnsTrueForAddedValues() {
|
||||
ExoFlags flags =
|
||||
new ExoFlags.Builder()
|
||||
.addIf(/* flag= */ -1234, /* condition= */ true)
|
||||
.addIf(/* flag= */ 0, /* condition= */ false)
|
||||
.addIf(/* flag= */ 2, /* condition= */ true)
|
||||
.addIf(/* flag= */ Integer.MAX_VALUE, /* condition= */ false)
|
||||
.build();
|
||||
|
||||
flags.clear();
|
||||
|
||||
assertThat(flags.contains(/* flag= */ -1234)).isFalse();
|
||||
assertThat(flags.contains(/* flag= */ -1235)).isFalse();
|
||||
assertThat(flags.contains(/* flag= */ -1234)).isTrue();
|
||||
assertThat(flags.contains(/* flag= */ 0)).isFalse();
|
||||
assertThat(flags.contains(/* flag= */ 2)).isFalse();
|
||||
assertThat(flags.contains(/* flag= */ 1)).isFalse();
|
||||
assertThat(flags.contains(/* flag= */ 2)).isTrue();
|
||||
assertThat(flags.contains(/* flag= */ Integer.MAX_VALUE - 1)).isFalse();
|
||||
assertThat(flags.contains(/* flag= */ Integer.MAX_VALUE)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsAny_withoutAdd_returnsFalseForAllValues() {
|
||||
ExoFlags flags = new ExoFlags.Builder().build();
|
||||
|
||||
assertThat(flags.containsAny(/* flags...= */ -1234, 0, 2, Integer.MAX_VALUE)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsAny_afterAdd_returnsTrueForAddedValues() {
|
||||
ExoFlags flags =
|
||||
new ExoFlags.Builder()
|
||||
.add(/* flag= */ -1234)
|
||||
.add(/* flag= */ 0)
|
||||
.add(/* flag= */ 2)
|
||||
.add(/* flag= */ Integer.MAX_VALUE)
|
||||
.build();
|
||||
|
||||
assertThat(
|
||||
flags.containsAny(
|
||||
/* flags...= */ -1235, -1234, 0, 1, 2, Integer.MAX_VALUE - 1, Integer.MAX_VALUE))
|
||||
.isTrue();
|
||||
assertThat(flags.containsAny(/* flags...= */ -1235, 1, Integer.MAX_VALUE - 1)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void size_withoutAdd_returnsZero() {
|
||||
MutableFlags flags = new MutableFlags();
|
||||
ExoFlags flags = new ExoFlags.Builder().build();
|
||||
|
||||
assertThat(flags.size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void size_afterAdd_returnsNumberUniqueOfElements() {
|
||||
MutableFlags flags = new MutableFlags();
|
||||
|
||||
flags.add(/* flag= */ 0);
|
||||
flags.add(/* flag= */ 0);
|
||||
flags.add(/* flag= */ 0);
|
||||
flags.add(/* flag= */ 123);
|
||||
flags.add(/* flag= */ 123);
|
||||
ExoFlags flags =
|
||||
new ExoFlags.Builder()
|
||||
.add(/* flag= */ 0)
|
||||
.add(/* flag= */ 0)
|
||||
.add(/* flag= */ 0)
|
||||
.add(/* flag= */ 123)
|
||||
.add(/* flag= */ 123)
|
||||
.build();
|
||||
|
||||
assertThat(flags.size()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void size_afterClear_returnsZero() {
|
||||
MutableFlags flags = new MutableFlags();
|
||||
|
||||
flags.add(/* flag= */ 0);
|
||||
flags.add(/* flag= */ 123);
|
||||
flags.clear();
|
||||
|
||||
assertThat(flags.size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void get_withNegativeIndex_throwsIllegalArgumentException() {
|
||||
MutableFlags flags = new MutableFlags();
|
||||
ExoFlags flags = new ExoFlags.Builder().build();
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () -> flags.get(/* index= */ -1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void get_withIndexExceedingSize_throwsIllegalArgumentException() {
|
||||
MutableFlags flags = new MutableFlags();
|
||||
|
||||
flags.add(/* flag= */ 0);
|
||||
flags.add(/* flag= */ 123);
|
||||
ExoFlags flags = new ExoFlags.Builder().add(/* flag= */ 0).add(/* flag= */ 123).build();
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () -> flags.get(/* index= */ 2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void get_afterAdd_returnsAllUniqueValues() {
|
||||
MutableFlags flags = new MutableFlags();
|
||||
|
||||
flags.add(/* flag= */ 0);
|
||||
flags.add(/* flag= */ 0);
|
||||
flags.add(/* flag= */ 0);
|
||||
flags.add(/* flag= */ 123);
|
||||
flags.add(/* flag= */ 123);
|
||||
flags.add(/* flag= */ 456);
|
||||
ExoFlags flags =
|
||||
new ExoFlags.Builder()
|
||||
.add(/* flag= */ 0)
|
||||
.add(/* flag= */ 0)
|
||||
.add(/* flag= */ 0)
|
||||
.add(/* flag= */ 123)
|
||||
.add(/* flag= */ 123)
|
||||
.add(/* flag= */ 456)
|
||||
.build();
|
||||
|
||||
List<Integer> values = new ArrayList<>();
|
||||
for (int i = 0; i < flags.size(); i++) {
|
@ -42,9 +42,8 @@ public class ListenerSetTest {
|
||||
|
||||
@Test
|
||||
public void queueEvent_withoutFlush_sendsNoEvents() {
|
||||
ListenerSet<TestListener, Flags> listenerSet =
|
||||
new ListenerSet<>(
|
||||
Looper.myLooper(), Clock.DEFAULT, Flags::new, TestListener::iterationFinished);
|
||||
ListenerSet<TestListener> listenerSet =
|
||||
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, TestListener::iterationFinished);
|
||||
TestListener listener = mock(TestListener.class);
|
||||
listenerSet.add(listener);
|
||||
|
||||
@ -57,9 +56,8 @@ public class ListenerSetTest {
|
||||
|
||||
@Test
|
||||
public void flushEvents_sendsPreviouslyQueuedEventsToAllListeners() {
|
||||
ListenerSet<TestListener, Flags> listenerSet =
|
||||
new ListenerSet<>(
|
||||
Looper.myLooper(), Clock.DEFAULT, Flags::new, TestListener::iterationFinished);
|
||||
ListenerSet<TestListener> listenerSet =
|
||||
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, TestListener::iterationFinished);
|
||||
TestListener listener1 = mock(TestListener.class);
|
||||
TestListener listener2 = mock(TestListener.class);
|
||||
listenerSet.add(listener1);
|
||||
@ -82,9 +80,8 @@ public class ListenerSetTest {
|
||||
|
||||
@Test
|
||||
public void flushEvents_recursive_sendsEventsInCorrectOrder() {
|
||||
ListenerSet<TestListener, Flags> listenerSet =
|
||||
new ListenerSet<>(
|
||||
Looper.myLooper(), Clock.DEFAULT, Flags::new, TestListener::iterationFinished);
|
||||
ListenerSet<TestListener> listenerSet =
|
||||
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, TestListener::iterationFinished);
|
||||
// Listener1 sends callback3 recursively when receiving callback1.
|
||||
TestListener listener1 =
|
||||
spy(
|
||||
@ -116,9 +113,8 @@ public class ListenerSetTest {
|
||||
@Test
|
||||
public void
|
||||
flushEvents_withMultipleMessageQueueIterations_sendsIterationFinishedEventPerIteration() {
|
||||
ListenerSet<TestListener, Flags> listenerSet =
|
||||
new ListenerSet<>(
|
||||
Looper.myLooper(), Clock.DEFAULT, Flags::new, TestListener::iterationFinished);
|
||||
ListenerSet<TestListener> listenerSet =
|
||||
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, TestListener::iterationFinished);
|
||||
// Listener1 sends callback1 recursively when receiving callback3.
|
||||
TestListener listener1 =
|
||||
spy(
|
||||
@ -152,30 +148,29 @@ public class ListenerSetTest {
|
||||
InOrder inOrder = Mockito.inOrder(listener1, listener2);
|
||||
inOrder.verify(listener1).callback2();
|
||||
inOrder.verify(listener2).callback2();
|
||||
inOrder.verify(listener1).iterationFinished(Flags.create(EVENT_ID_2));
|
||||
inOrder.verify(listener2).iterationFinished(Flags.create(EVENT_ID_2));
|
||||
inOrder.verify(listener1).iterationFinished(createExoFlags(EVENT_ID_2));
|
||||
inOrder.verify(listener2).iterationFinished(createExoFlags(EVENT_ID_2));
|
||||
inOrder.verify(listener1).callback1();
|
||||
inOrder.verify(listener2).callback1();
|
||||
inOrder.verify(listener1).callback2();
|
||||
inOrder.verify(listener2).callback2();
|
||||
inOrder.verify(listener1).callback1();
|
||||
inOrder.verify(listener2).callback1();
|
||||
inOrder.verify(listener1).iterationFinished(Flags.create(EVENT_ID_1, EVENT_ID_2));
|
||||
inOrder.verify(listener2).iterationFinished(Flags.create(EVENT_ID_1, EVENT_ID_2));
|
||||
inOrder.verify(listener1).iterationFinished(createExoFlags(EVENT_ID_1, EVENT_ID_2));
|
||||
inOrder.verify(listener2).iterationFinished(createExoFlags(EVENT_ID_1, EVENT_ID_2));
|
||||
inOrder.verify(listener1).callback3();
|
||||
inOrder.verify(listener2).callback3();
|
||||
inOrder.verify(listener1).callback1();
|
||||
inOrder.verify(listener2).callback1();
|
||||
inOrder.verify(listener1).iterationFinished(Flags.create(EVENT_ID_1, EVENT_ID_3));
|
||||
inOrder.verify(listener2).iterationFinished(Flags.create(EVENT_ID_1, EVENT_ID_3));
|
||||
inOrder.verify(listener1).iterationFinished(createExoFlags(EVENT_ID_1, EVENT_ID_3));
|
||||
inOrder.verify(listener2).iterationFinished(createExoFlags(EVENT_ID_1, EVENT_ID_3));
|
||||
inOrder.verifyNoMoreInteractions();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void flushEvents_calledFromIterationFinishedCallback_restartsIterationFinishedEvents() {
|
||||
ListenerSet<TestListener, Flags> listenerSet =
|
||||
new ListenerSet<>(
|
||||
Looper.myLooper(), Clock.DEFAULT, Flags::new, TestListener::iterationFinished);
|
||||
ListenerSet<TestListener> listenerSet =
|
||||
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, TestListener::iterationFinished);
|
||||
// Listener2 sends callback1 recursively when receiving the iteration finished event.
|
||||
TestListener listener2 =
|
||||
spy(
|
||||
@ -183,7 +178,7 @@ public class ListenerSetTest {
|
||||
boolean eventSent;
|
||||
|
||||
@Override
|
||||
public void iterationFinished(Flags flags) {
|
||||
public void iterationFinished(ExoFlags flags) {
|
||||
if (!eventSent) {
|
||||
listenerSet.sendEvent(EVENT_ID_1, TestListener::callback1);
|
||||
eventSent = true;
|
||||
@ -203,22 +198,21 @@ public class ListenerSetTest {
|
||||
inOrder.verify(listener1).callback2();
|
||||
inOrder.verify(listener2).callback2();
|
||||
inOrder.verify(listener3).callback2();
|
||||
inOrder.verify(listener1).iterationFinished(Flags.create(EVENT_ID_2));
|
||||
inOrder.verify(listener2).iterationFinished(Flags.create(EVENT_ID_2));
|
||||
inOrder.verify(listener1).iterationFinished(createExoFlags(EVENT_ID_2));
|
||||
inOrder.verify(listener2).iterationFinished(createExoFlags(EVENT_ID_2));
|
||||
inOrder.verify(listener1).callback1();
|
||||
inOrder.verify(listener2).callback1();
|
||||
inOrder.verify(listener3).callback1();
|
||||
inOrder.verify(listener1).iterationFinished(Flags.create(EVENT_ID_1));
|
||||
inOrder.verify(listener2).iterationFinished(Flags.create(EVENT_ID_1));
|
||||
inOrder.verify(listener3).iterationFinished(Flags.create(EVENT_ID_1, EVENT_ID_2));
|
||||
inOrder.verify(listener1).iterationFinished(createExoFlags(EVENT_ID_1));
|
||||
inOrder.verify(listener2).iterationFinished(createExoFlags(EVENT_ID_1));
|
||||
inOrder.verify(listener3).iterationFinished(createExoFlags(EVENT_ID_1, EVENT_ID_2));
|
||||
inOrder.verifyNoMoreInteractions();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void flushEvents_withUnsetEventFlag_doesNotThrow() {
|
||||
ListenerSet<TestListener, Flags> listenerSet =
|
||||
new ListenerSet<>(
|
||||
Looper.myLooper(), Clock.DEFAULT, Flags::new, TestListener::iterationFinished);
|
||||
ListenerSet<TestListener> listenerSet =
|
||||
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, TestListener::iterationFinished);
|
||||
|
||||
listenerSet.queueEvent(/* eventFlag= */ C.INDEX_UNSET, TestListener::callback1);
|
||||
listenerSet.flushEvents();
|
||||
@ -229,9 +223,8 @@ public class ListenerSetTest {
|
||||
|
||||
@Test
|
||||
public void add_withRecursion_onlyReceivesUpdatesForFutureEvents() {
|
||||
ListenerSet<TestListener, Flags> listenerSet =
|
||||
new ListenerSet<>(
|
||||
Looper.myLooper(), Clock.DEFAULT, Flags::new, TestListener::iterationFinished);
|
||||
ListenerSet<TestListener> listenerSet =
|
||||
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, TestListener::iterationFinished);
|
||||
TestListener listener2 = mock(TestListener.class);
|
||||
// Listener1 adds listener2 recursively.
|
||||
TestListener listener1 =
|
||||
@ -255,16 +248,15 @@ public class ListenerSetTest {
|
||||
inOrder.verify(listener1).callback1();
|
||||
inOrder.verify(listener1).callback2();
|
||||
inOrder.verify(listener2).callback2();
|
||||
inOrder.verify(listener1).iterationFinished(Flags.create(EVENT_ID_1, EVENT_ID_2));
|
||||
inOrder.verify(listener2).iterationFinished(Flags.create(EVENT_ID_2));
|
||||
inOrder.verify(listener1).iterationFinished(createExoFlags(EVENT_ID_1, EVENT_ID_2));
|
||||
inOrder.verify(listener2).iterationFinished(createExoFlags(EVENT_ID_2));
|
||||
inOrder.verifyNoMoreInteractions();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void add_withQueueing_onlyReceivesUpdatesForFutureEvents() {
|
||||
ListenerSet<TestListener, Flags> listenerSet =
|
||||
new ListenerSet<>(
|
||||
Looper.myLooper(), Clock.DEFAULT, Flags::new, TestListener::iterationFinished);
|
||||
ListenerSet<TestListener> listenerSet =
|
||||
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, TestListener::iterationFinished);
|
||||
TestListener listener1 = mock(TestListener.class);
|
||||
TestListener listener2 = mock(TestListener.class);
|
||||
|
||||
@ -281,16 +273,15 @@ public class ListenerSetTest {
|
||||
inOrder.verify(listener1).callback1();
|
||||
inOrder.verify(listener1).callback2();
|
||||
inOrder.verify(listener2).callback2();
|
||||
inOrder.verify(listener1).iterationFinished(Flags.create(EVENT_ID_1, EVENT_ID_2));
|
||||
inOrder.verify(listener2).iterationFinished(Flags.create(EVENT_ID_2));
|
||||
inOrder.verify(listener1).iterationFinished(createExoFlags(EVENT_ID_1, EVENT_ID_2));
|
||||
inOrder.verify(listener2).iterationFinished(createExoFlags(EVENT_ID_2));
|
||||
inOrder.verifyNoMoreInteractions();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void remove_withRecursion_stopsReceivingEventsImmediately() {
|
||||
ListenerSet<TestListener, Flags> listenerSet =
|
||||
new ListenerSet<>(
|
||||
Looper.myLooper(), Clock.DEFAULT, Flags::new, TestListener::iterationFinished);
|
||||
ListenerSet<TestListener> listenerSet =
|
||||
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, TestListener::iterationFinished);
|
||||
TestListener listener2 = mock(TestListener.class);
|
||||
// Listener1 removes listener2 recursively.
|
||||
TestListener listener1 =
|
||||
@ -311,15 +302,14 @@ public class ListenerSetTest {
|
||||
ShadowLooper.runMainLooperToNextTask();
|
||||
|
||||
verify(listener1).callback1();
|
||||
verify(listener1).iterationFinished(Flags.create(EVENT_ID_1));
|
||||
verify(listener1).iterationFinished(createExoFlags(EVENT_ID_1));
|
||||
verifyNoMoreInteractions(listener1, listener2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void remove_withQueueing_stopsReceivingEventsImmediately() {
|
||||
ListenerSet<TestListener, Flags> listenerSet =
|
||||
new ListenerSet<>(
|
||||
Looper.myLooper(), Clock.DEFAULT, Flags::new, TestListener::iterationFinished);
|
||||
ListenerSet<TestListener> listenerSet =
|
||||
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, TestListener::iterationFinished);
|
||||
TestListener listener1 = mock(TestListener.class);
|
||||
TestListener listener2 = mock(TestListener.class);
|
||||
listenerSet.add(listener1);
|
||||
@ -333,15 +323,14 @@ public class ListenerSetTest {
|
||||
ShadowLooper.runMainLooperToNextTask();
|
||||
|
||||
verify(listener2, times(2)).callback1();
|
||||
verify(listener2).iterationFinished(Flags.create(EVENT_ID_1));
|
||||
verify(listener2).iterationFinished(createExoFlags(EVENT_ID_1));
|
||||
verifyNoMoreInteractions(listener1, listener2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void release_stopsForwardingEventsImmediately() {
|
||||
ListenerSet<TestListener, Flags> listenerSet =
|
||||
new ListenerSet<>(
|
||||
Looper.myLooper(), Clock.DEFAULT, Flags::new, TestListener::iterationFinished);
|
||||
ListenerSet<TestListener> listenerSet =
|
||||
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, TestListener::iterationFinished);
|
||||
TestListener listener2 = mock(TestListener.class);
|
||||
// Listener1 releases the set from within the callback.
|
||||
TestListener listener1 =
|
||||
@ -361,15 +350,14 @@ public class ListenerSetTest {
|
||||
ShadowLooper.runMainLooperToNextTask();
|
||||
|
||||
verify(listener1).callback1();
|
||||
verify(listener1).iterationFinished(Flags.create(EVENT_ID_1));
|
||||
verify(listener1).iterationFinished(createExoFlags(EVENT_ID_1));
|
||||
verifyNoMoreInteractions(listener1, listener2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void release_preventsRegisteringNewListeners() {
|
||||
ListenerSet<TestListener, Flags> listenerSet =
|
||||
new ListenerSet<>(
|
||||
Looper.myLooper(), Clock.DEFAULT, Flags::new, TestListener::iterationFinished);
|
||||
ListenerSet<TestListener> listenerSet =
|
||||
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, TestListener::iterationFinished);
|
||||
TestListener listener = mock(TestListener.class);
|
||||
|
||||
listenerSet.release();
|
||||
@ -381,9 +369,8 @@ public class ListenerSetTest {
|
||||
|
||||
@Test
|
||||
public void lazyRelease_stopsForwardingEventsFromNewHandlerMessagesAndCallsReleaseCallback() {
|
||||
ListenerSet<TestListener, Flags> listenerSet =
|
||||
new ListenerSet<>(
|
||||
Looper.myLooper(), Clock.DEFAULT, Flags::new, TestListener::iterationFinished);
|
||||
ListenerSet<TestListener> listenerSet =
|
||||
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, TestListener::iterationFinished);
|
||||
TestListener listener = mock(TestListener.class);
|
||||
listenerSet.add(listener);
|
||||
|
||||
@ -403,8 +390,8 @@ public class ListenerSetTest {
|
||||
// lazy release.
|
||||
verify(listener, times(3)).callback1();
|
||||
verify(listener).callback3();
|
||||
verify(listener).iterationFinished(Flags.create(EVENT_ID_1));
|
||||
verify(listener).iterationFinished(Flags.create(EVENT_ID_1, EVENT_ID_3));
|
||||
verify(listener).iterationFinished(createExoFlags(EVENT_ID_1));
|
||||
verify(listener).iterationFinished(createExoFlags(EVENT_ID_1, EVENT_ID_3));
|
||||
verifyNoMoreInteractions(listener);
|
||||
}
|
||||
|
||||
@ -415,17 +402,14 @@ public class ListenerSetTest {
|
||||
|
||||
default void callback3() {}
|
||||
|
||||
default void iterationFinished(Flags flags) {}
|
||||
default void iterationFinished(ExoFlags flags) {}
|
||||
}
|
||||
|
||||
private static final class Flags extends MutableFlags {
|
||||
|
||||
public static Flags create(int... flagValues) {
|
||||
Flags flags = new Flags();
|
||||
for (int value : flagValues) {
|
||||
flags.add(value);
|
||||
}
|
||||
return flags;
|
||||
private static ExoFlags createExoFlags(int... flagValues) {
|
||||
ExoFlags.Builder flagsBuilder = new ExoFlags.Builder();
|
||||
for (int value : flagValues) {
|
||||
flagsBuilder.add(value);
|
||||
}
|
||||
return flagsBuilder.build();
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ import java.util.List;
|
||||
private final HandlerWrapper playbackInfoUpdateHandler;
|
||||
private final ExoPlayerImplInternal.PlaybackInfoUpdateListener playbackInfoUpdateListener;
|
||||
private final ExoPlayerImplInternal internalPlayer;
|
||||
private final ListenerSet<Player.EventListener, Player.Events> listeners;
|
||||
private final ListenerSet<Player.EventListener> listeners;
|
||||
private final Timeline.Period period;
|
||||
private final List<MediaSourceHolderSnapshot> mediaSourceHolderSnapshots;
|
||||
private final boolean useLazyPreparation;
|
||||
@ -165,8 +165,7 @@ import java.util.List;
|
||||
new ListenerSet<>(
|
||||
applicationLooper,
|
||||
clock,
|
||||
Player.Events::new,
|
||||
(listener, eventFlags) -> listener.onEvents(playerForListeners, eventFlags));
|
||||
(listener, flags) -> listener.onEvents(playerForListeners, new Events(flags)));
|
||||
mediaSourceHolderSnapshots = new ArrayList<>();
|
||||
shuffleOrder = new ShuffleOrder.DefaultShuffleOrder(/* length= */ 0);
|
||||
emptyTrackSelectorResult =
|
||||
|
@ -78,7 +78,7 @@ public class AnalyticsCollector
|
||||
private final MediaPeriodQueueTracker mediaPeriodQueueTracker;
|
||||
private final SparseArray<EventTime> eventTimes;
|
||||
|
||||
private ListenerSet<AnalyticsListener, AnalyticsListener.Events> listeners;
|
||||
private ListenerSet<AnalyticsListener> listeners;
|
||||
private @MonotonicNonNull Player player;
|
||||
private boolean isSeeking;
|
||||
|
||||
@ -89,12 +89,7 @@ public class AnalyticsCollector
|
||||
*/
|
||||
public AnalyticsCollector(Clock clock) {
|
||||
this.clock = checkNotNull(clock);
|
||||
listeners =
|
||||
new ListenerSet<>(
|
||||
Util.getCurrentOrMainLooper(),
|
||||
clock,
|
||||
AnalyticsListener.Events::new,
|
||||
(listener, eventFlags) -> {});
|
||||
listeners = new ListenerSet<>(Util.getCurrentOrMainLooper(), clock, (listener, flags) -> {});
|
||||
period = new Period();
|
||||
window = new Window();
|
||||
mediaPeriodQueueTracker = new MediaPeriodQueueTracker(period);
|
||||
@ -137,10 +132,8 @@ public class AnalyticsCollector
|
||||
listeners =
|
||||
listeners.copy(
|
||||
looper,
|
||||
(listener, events) -> {
|
||||
events.setEventTimes(eventTimes);
|
||||
listener.onEvents(player, events);
|
||||
});
|
||||
(listener, flags) ->
|
||||
listener.onEvents(player, new AnalyticsListener.Events(flags, eventTimes)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,7 +47,7 @@ import com.google.android.exoplayer2.source.MediaLoadData;
|
||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.util.MutableFlags;
|
||||
import com.google.android.exoplayer2.util.ExoFlags;
|
||||
import com.google.common.base.Objects;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Documented;
|
||||
@ -70,13 +70,27 @@ import java.util.List;
|
||||
public interface AnalyticsListener {
|
||||
|
||||
/** A set of {@link EventFlags}. */
|
||||
final class Events extends MutableFlags {
|
||||
final class Events {
|
||||
|
||||
private final ExoFlags flags;
|
||||
private final SparseArray<EventTime> eventTimes;
|
||||
|
||||
/** Creates the set of event flags. */
|
||||
public Events() {
|
||||
eventTimes = new SparseArray<>(/* initialCapacity= */ 0);
|
||||
/**
|
||||
* Creates an instance.
|
||||
*
|
||||
* @param flags The {@link ExoFlags} containing the {@link EventFlags} in the set.
|
||||
* @param eventTimes A map from {@link EventFlags} to {@link EventTime}. Must at least contain
|
||||
* all the events recorded in {@code flags}. Events that are not recorded in {@code flags}
|
||||
* are ignored.
|
||||
*/
|
||||
public Events(ExoFlags flags, SparseArray<EventTime> eventTimes) {
|
||||
this.flags = flags;
|
||||
SparseArray<EventTime> flagsToTimes = new SparseArray<>(/* initialCapacity= */ flags.size());
|
||||
for (int i = 0; i < flags.size(); i++) {
|
||||
@EventFlags int eventFlag = flags.get(i);
|
||||
flagsToTimes.append(eventFlag, checkNotNull(eventTimes.get(eventFlag)));
|
||||
}
|
||||
this.eventTimes = flagsToTimes;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,30 +103,14 @@ public interface AnalyticsListener {
|
||||
return checkNotNull(eventTimes.get(event));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link EventTime} values for events recorded in this set.
|
||||
*
|
||||
* @param eventTimes A map from {@link EventFlags} to {@link EventTime}. Must at least contain
|
||||
* all the events recorded in this set.
|
||||
*/
|
||||
public void setEventTimes(SparseArray<EventTime> eventTimes) {
|
||||
this.eventTimes.clear();
|
||||
for (int i = 0; i < size(); i++) {
|
||||
@EventFlags int eventFlag = get(i);
|
||||
this.eventTimes.append(eventFlag, checkNotNull(eventTimes.get(eventFlag)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given event occurred.
|
||||
*
|
||||
* @param event The {@link EventFlags event}.
|
||||
* @return Whether the event occurred.
|
||||
*/
|
||||
@Override
|
||||
public boolean contains(@EventFlags int event) {
|
||||
// Overridden to add IntDef compiler enforcement and new JavaDoc.
|
||||
return super.contains(event);
|
||||
return flags.contains(event);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,10 +119,13 @@ public interface AnalyticsListener {
|
||||
* @param events The {@link EventFlags events}.
|
||||
* @return Whether any of the events occurred.
|
||||
*/
|
||||
@Override
|
||||
public boolean containsAny(@EventFlags int... events) {
|
||||
// Overridden to add IntDef compiler enforcement and new JavaDoc.
|
||||
return super.containsAny(events);
|
||||
return flags.containsAny(events);
|
||||
}
|
||||
|
||||
/** Returns the number of events in the set. */
|
||||
public int size() {
|
||||
return flags.size();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -136,11 +137,9 @@ public interface AnalyticsListener {
|
||||
* @param index The index. Must be between 0 (inclusive) and {@link #size()} (exclusive).
|
||||
* @return The {@link EventFlags event} at the given index.
|
||||
*/
|
||||
@Override
|
||||
@EventFlags
|
||||
public int get(int index) {
|
||||
// Overridden to add IntDef compiler enforcement and new JavaDoc.
|
||||
return super.get(index);
|
||||
return flags.get(index);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user