Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
4a6859e5
authored
Mar 10, 2021
by
kimvde
Committed by
Ian Baker
Mar 12, 2021
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Replace MutableFlags by immutable class
PiperOrigin-RevId: 362043183
parent
851c915e
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
233 additions
and
207 deletions
extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java
extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/FakePlayer.java
library/common/src/main/java/com/google/android/exoplayer2/Player.java
library/common/src/main/java/com/google/android/exoplayer2/util/MutableFlags.java → library/common/src/main/java/com/google/android/exoplayer2/util/ExoFlags.java
library/common/src/main/java/com/google/android/exoplayer2/util/ListenerSet.java
library/core/src/test/java/com/google/android/exoplayer2/util/MutableFlagsTest.java → library/common/src/test/java/com/google/android/exoplayer2/util/ExoFlagsTest.java
library/common/src/test/java/com/google/android/exoplayer2/util/ListenerSetTest.java
library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java
library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java
library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsListener.java
extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java
View file @
4a6859e5
...
...
@@ -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
);
...
...
extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/FakePlayer.java
View file @
4a6859e5
...
...
@@ -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
;
...
...
library/common/src/main/java/com/google/android/exoplayer2/Player.java
View file @
4a6859e5
...
...
@@ -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.
Mutable
Flags
;
import
com.google.android.exoplayer2.util.
Exo
Flags
;
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
Commands
(
SparseBooleanArray
commandsArray
)
{
this
.
commandsArray
=
commandsArray
;
}
private
final
ExoFlags
flags
;
/** 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
();
}
}
...
...
library/common/src/main/java/com/google/android/exoplayer2/util/
Mutable
Flags.java
→
library/common/src/main/java/com/google/android/exoplayer2/util/
Exo
Flags.java
View file @
4a6859e5
...
...
@@ -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
Mutable
Flags
{
public
final
class
Exo
Flags
{
private
final
SparseBooleanArray
flags
;
/** A builder for {@link ExoFlags} instances. */
public
static
final
class
Builder
{
/** Creates the set of flags. */
public
MutableFlags
()
{
flags
=
new
SparseBooleanArray
();
}
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
;
}
/** Clears all previously set flags. */
public
void
clear
()
{
flags
.
clear
();
/**
* 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
);
}
}
/**
* Adds a flag to the set.
*
* @param flag The flag to add.
*/
public
void
add
(
int
flag
)
{
flags
.
append
(
flag
,
/* value= */
true
);
// A SparseBooleanArray is used instead of a Set to avoid auto-boxing the flag values.
private
final
SparseBooleanArray
flags
;
private
ExoFlags
(
SparseBooleanArray
flags
)
{
this
.
flags
=
flags
;
}
/**
...
...
@@ -94,10 +136,10 @@ public class MutableFlags {
if
(
this
==
o
)
{
return
true
;
}
if
(!(
o
instanceof
Mutable
Flags
))
{
if
(!(
o
instanceof
Exo
Flags
))
{
return
false
;
}
MutableFlags
that
=
(
Mutable
Flags
)
o
;
ExoFlags
that
=
(
Exo
Flags
)
o
;
return
flags
.
equals
(
that
.
flags
);
}
...
...
library/common/src/main/java/com/google/android/exoplayer2/util/ListenerSet.java
View file @
4a6859e5
...
...
@@ -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
,
E
xoFlags
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
E
xoFlags
.
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
();
E
xoFlags
flagsToNotify
=
flagsBuilder
.
build
()
;
flagsBuilder
=
new
ExoFlags
.
Builder
();
needsIterationFinishedEvent
=
false
;
event
.
invoke
(
listener
,
flagToNotify
);
event
.
invoke
(
listener
,
flag
s
ToNotify
);
}
}
...
...
@@ -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
...
...
library/co
re/src/test/java/com/google/android/exoplayer2/util/Mutable
FlagsTest.java
→
library/co
mmon/src/test/java/com/google/android/exoplayer2/util/Exo
FlagsTest.java
View file @
4a6859e5
...
...
@@ -24,13 +24,13 @@ import java.util.List;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
/** Unit test for {@link
Mutable
Flags}. */
/** Unit test for {@link
Exo
Flags}. */
@RunWith
(
AndroidJUnit4
.
class
)
public
final
class
Mutable
FlagsTest
{
public
final
class
Exo
FlagsTest
{
@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_after
Clear_returnsFalseForAll
Values
()
{
MutableFlags
flags
=
new
MutableFlags
();
flags
.
add
(
/* flag= */
-
1234
);
flags
.
add
(
/* flag= */
0
);
flags
.
add
(
/* flag= */
2
);
flags
.
add
(
/* flag= */
Integer
.
MAX_VALUE
);
flags
.
clear
();
public
void
contains_after
AddIf_returnsTrueForAdded
Values
()
{
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
();
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
size_withoutAdd_returnsZero
()
{
MutableFlags
flags
=
new
MutableFlags
();
public
void
containsAny_withoutAdd_returnsFalseForAllValues
()
{
ExoFlags
flags
=
new
ExoFlags
.
Builder
().
build
();
assertThat
(
flags
.
size
()).
isEqualTo
(
0
);
assertThat
(
flags
.
containsAny
(
/* flags...= */
-
1234
,
0
,
2
,
Integer
.
MAX_VALUE
)).
isFalse
(
);
}
@Test
public
void
size_afterAdd_returnsNumberUniqueOfElements
()
{
MutableFlags
flags
=
new
MutableFlags
();
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
();
}
flags
.
add
(
/* flag= */
0
);
flags
.
add
(
/* flag= */
0
);
flags
.
add
(
/* flag= */
0
);
flags
.
add
(
/* flag= */
123
);
flags
.
add
(
/* flag= */
123
);
@Test
public
void
size_withoutAdd_returnsZero
()
{
ExoFlags
flags
=
new
ExoFlags
.
Builder
().
build
();
assertThat
(
flags
.
size
()).
isEqualTo
(
2
);
assertThat
(
flags
.
size
()).
isEqualTo
(
0
);
}
@Test
public
void
size_afterClear_returnsZero
()
{
MutableFlags
flags
=
new
MutableFlags
();
flags
.
add
(
/* flag= */
0
);
flags
.
add
(
/* flag= */
123
);
flags
.
clear
();
public
void
size_afterAdd_returnsNumberUniqueOfElements
()
{
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
(
0
);
assertThat
(
flags
.
size
()).
isEqualTo
(
2
);
}
@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
++)
{
...
...
library/common/src/test/java/com/google/android/exoplayer2/util/ListenerSetTest.java
View file @
4a6859e5
This diff is collapsed.
Click to expand it.
library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java
View file @
4a6859e5
...
...
@@ -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
=
...
...
library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java
View file @
4a6859e5
...
...
@@ -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
)));
}
/**
...
...
library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsListener.java
View file @
4a6859e5
...
...
@@ -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.
Mutable
Flags
;
import
com.google.android.exoplayer2.util.
Exo
Flags
;
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
;
}
/**
...
...
@@ -90,29 +104,13 @@ public interface AnalyticsListener {
}
/**
* 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
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment