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
764e5e81
authored
Nov 06, 2020
by
andrewlewis
Committed by
Andrew Lewis
Nov 06, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Expose the ads identifier in the Timeline period
Issue: #3750 PiperOrigin-RevId: 341021084
parent
0c301fef
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
143 additions
and
81 deletions
extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/AdTagLoader.java
extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java
extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaUtil.java
extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoaderTest.java
library/core/src/main/java/com/google/android/exoplayer2/Timeline.java
library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java
library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java
library/core/src/test/java/com/google/android/exoplayer2/MediaPeriodQueueTest.java
library/core/src/test/java/com/google/android/exoplayer2/analytics/DefaultPlaybackSessionManagerTest.java
library/core/src/test/java/com/google/android/exoplayer2/source/ads/AdPlaybackStateTest.java
library/core/src/test/java/com/google/android/exoplayer2/source/ads/AdsMediaSourceTest.java
testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTimeline.java
extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/AdTagLoader.java
View file @
764e5e81
...
...
@@ -128,6 +128,7 @@ import java.util.Map;
private
final
ImaUtil
.
ImaFactory
imaFactory
;
private
final
List
<
String
>
supportedMimeTypes
;
private
final
DataSpec
adTagDataSpec
;
private
final
Object
adsId
;
private
final
Timeline
.
Period
period
;
private
final
Handler
handler
;
private
final
ComponentListener
componentListener
;
...
...
@@ -146,7 +147,6 @@ import java.util.Map;
@Nullable
private
AdsManager
adsManager
;
private
boolean
isAdsManagerInitialized
;
private
boolean
hasAdPlaybackState
;
@Nullable
private
AdLoadException
pendingAdLoadError
;
private
Timeline
timeline
;
private
long
contentDurationMs
;
...
...
@@ -214,6 +214,7 @@ import java.util.Map;
ImaUtil
.
ImaFactory
imaFactory
,
List
<
String
>
supportedMimeTypes
,
DataSpec
adTagDataSpec
,
Object
adsId
,
@Nullable
ViewGroup
adViewGroup
)
{
this
.
configuration
=
configuration
;
this
.
imaFactory
=
imaFactory
;
...
...
@@ -228,6 +229,7 @@ import java.util.Map;
imaSdkSettings
.
setPlayerVersion
(
IMA_SDK_SETTINGS_PLAYER_VERSION
);
this
.
supportedMimeTypes
=
supportedMimeTypes
;
this
.
adTagDataSpec
=
adTagDataSpec
;
this
.
adsId
=
adsId
;
period
=
new
Timeline
.
Period
();
handler
=
Util
.
createHandler
(
getImaLooper
(),
/* callback= */
null
);
componentListener
=
new
ComponentListener
();
...
...
@@ -286,14 +288,16 @@ import java.util.Map;
lastAdProgress
=
VideoProgressUpdate
.
VIDEO_TIME_NOT_READY
;
lastContentProgress
=
VideoProgressUpdate
.
VIDEO_TIME_NOT_READY
;
maybeNotifyPendingAdLoadError
();
if
(
hasAdPlaybackState
)
{
if
(
!
AdPlaybackState
.
NONE
.
equals
(
adPlaybackState
)
)
{
// Pass the ad playback state to the player, and resume ads if necessary.
eventListener
.
onAdPlaybackState
(
adPlaybackState
);
if
(
adsManager
!=
null
&&
imaPausedContent
&&
playWhenReady
)
{
adsManager
.
resume
();
}
}
else
if
(
adsManager
!=
null
)
{
adPlaybackState
=
ImaUtil
.
getInitialAdPlaybackStateForCuePoints
(
adsManager
.
getAdCuePoints
());
adPlaybackState
=
new
AdPlaybackState
(
adsId
,
ImaUtil
.
getAdGroupTimesUsForCuePoints
(
adsManager
.
getAdCuePoints
()));
updateAdPlaybackState
();
}
if
(
adDisplayContainer
!=
null
)
{
...
...
@@ -348,8 +352,7 @@ import java.util.Map;
stopUpdatingAdProgress
();
imaAdInfo
=
null
;
pendingAdLoadError
=
null
;
adPlaybackState
=
AdPlaybackState
.
NONE
;
hasAdPlaybackState
=
true
;
adPlaybackState
=
new
AdPlaybackState
(
adsId
);
updateAdPlaybackState
();
}
...
...
@@ -496,7 +499,7 @@ import java.util.Map;
try
{
request
=
ImaUtil
.
getAdsRequestForAdTagDataSpec
(
imaFactory
,
adTagDataSpec
);
}
catch
(
IOException
e
)
{
hasAdPlaybackState
=
true
;
adPlaybackState
=
new
AdPlaybackState
(
adsId
)
;
updateAdPlaybackState
();
pendingAdLoadError
=
AdLoadException
.
createForAllAds
(
e
);
maybeNotifyPendingAdLoadError
();
...
...
@@ -1215,8 +1218,8 @@ import java.util.Map;
// If a player is attached already, start playback immediately.
try
{
adPlaybackState
=
ImaUtil
.
getInitialAdPlaybackStateForCuePoints
(
adsManager
.
getAdCuePoints
());
hasAdPlaybackState
=
true
;
new
AdPlaybackState
(
adsId
,
ImaUtil
.
getAdGroupTimesUsForCuePoints
(
adsManager
.
getAdCuePoints
()))
;
updateAdPlaybackState
();
}
catch
(
RuntimeException
e
)
{
maybeNotifyInternalError
(
"onAdsManagerLoaded"
,
e
);
...
...
@@ -1276,8 +1279,7 @@ import java.util.Map;
if
(
adsManager
==
null
)
{
// No ads were loaded, so allow playback to start without any ads.
pendingAdRequestContext
=
null
;
adPlaybackState
=
AdPlaybackState
.
NONE
;
hasAdPlaybackState
=
true
;
adPlaybackState
=
new
AdPlaybackState
(
adsId
);
updateAdPlaybackState
();
}
else
if
(
ImaUtil
.
isAdGroupLoadError
(
error
))
{
try
{
...
...
extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java
View file @
764e5e81
...
...
@@ -417,14 +417,21 @@ public final class ImaAdsLoader
*
* @param adTagDataSpec The data specification of the ad tag to load. See class javadoc for
* information about compatible ad tag formats.
* @param adsId A opaque identifier for the ad playback state across start/stop calls.
* @param adViewGroup A {@link ViewGroup} on top of the player that will show any ad UI, or {@code
* null} if playing audio-only ads.
*/
public
void
requestAds
(
DataSpec
adTagDataSpec
,
@Nullable
ViewGroup
adViewGroup
)
{
public
void
requestAds
(
DataSpec
adTagDataSpec
,
Object
adsId
,
@Nullable
ViewGroup
adViewGroup
)
{
if
(
adTagLoader
==
null
)
{
adTagLoader
=
new
AdTagLoader
(
context
,
configuration
,
imaFactory
,
supportedMimeTypes
,
adTagDataSpec
,
adViewGroup
);
context
,
configuration
,
imaFactory
,
supportedMimeTypes
,
adTagDataSpec
,
adsId
,
adViewGroup
);
}
}
...
...
@@ -488,7 +495,7 @@ public final class ImaAdsLoader
return
;
}
if
(
adTagLoader
==
null
)
{
requestAds
(
adTagDataSpec
,
adViewProvider
.
getAdViewGroup
());
requestAds
(
adTagDataSpec
,
ad
sId
,
ad
ViewProvider
.
getAdViewGroup
());
}
checkNotNull
(
adTagLoader
).
start
(
player
,
adViewProvider
,
eventListener
);
}
...
...
extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaUtil.java
View file @
764e5e81
...
...
@@ -36,7 +36,6 @@ import com.google.ads.interactivemedia.v3.api.UiElement;
import
com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer
;
import
com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.source.ads.AdPlaybackState
;
import
com.google.android.exoplayer2.source.ads.AdsLoader.OverlayInfo
;
import
com.google.android.exoplayer2.upstream.DataSchemeDataSource
;
import
com.google.android.exoplayer2.upstream.DataSpec
;
...
...
@@ -154,15 +153,14 @@ import java.util.Set;
}
/**
* Returns
an initial {@link AdPlaybackState} with ad groups at the provided {@code cuePoints}
.
* Returns
the microsecond ad group timestamps corresponding to the specified cue points
.
*
* @param cuePoints The cue points of the ads in seconds.
* @return The
{@link AdPlaybackState}
.
* @param cuePoints The cue points of the ads in seconds
, provided by the IMA SDK
.
* @return The
corresponding microsecond ad group timestamps
.
*/
public
static
AdPlaybackState
getInitialAdPlaybackState
ForCuePoints
(
List
<
Float
>
cuePoints
)
{
public
static
long
[]
getAdGroupTimesUs
ForCuePoints
(
List
<
Float
>
cuePoints
)
{
if
(
cuePoints
.
isEmpty
())
{
// If no cue points are specified, there is a preroll ad.
return
new
AdPlaybackState
(
/* adGroupTimesUs...= */
0
);
return
new
long
[]
{
0L
};
}
int
count
=
cuePoints
.
size
();
...
...
@@ -178,7 +176,7 @@ import java.util.Set;
}
// Cue points may be out of order, so sort them.
Arrays
.
sort
(
adGroupTimesUs
,
0
,
adGroupIndex
);
return
new
AdPlaybackState
(
adGroupTimesUs
)
;
return
adGroupTimesUs
;
}
/** Returns an {@link AdsRequest} based on the specified ad tag {@link DataSpec}. */
...
...
extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoaderTest.java
View file @
764e5e81
...
...
@@ -16,6 +16,7 @@
package
com
.
google
.
android
.
exoplayer2
.
ext
.
ima
;
import
static
androidx
.
test
.
core
.
app
.
ApplicationProvider
.
getApplicationContext
;
import
static
com
.
google
.
android
.
exoplayer2
.
ext
.
ima
.
ImaUtil
.
getAdGroupTimesUsForCuePoints
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
static
org
.
mockito
.
ArgumentMatchers
.
any
;
import
static
org
.
mockito
.
ArgumentMatchers
.
anyDouble
;
...
...
@@ -226,7 +227,7 @@ public final class ImaAdsLoaderTest {
assertThat
(
adsLoaderListener
.
adPlaybackState
)
.
isEqualTo
(
new
AdPlaybackState
(
/* adGroupTimesUs...= */
0
)
new
AdPlaybackState
(
TEST_ADS_ID
,
/* adGroupTimesUs...= */
0
)
.
withContentDurationUs
(
CONTENT_PERIOD_DURATION_US
));
}
...
...
@@ -242,7 +243,7 @@ public final class ImaAdsLoaderTest {
public
void
startAndCallbacksAfterRelease
()
{
setupPlayback
(
CONTENT_TIMELINE
,
PREROLL_CUE_POINTS_SECONDS
);
// Request ads in order to get a reference to the ad event listener.
imaAdsLoader
.
requestAds
(
TEST_DATA_SPEC
,
adViewGroup
);
imaAdsLoader
.
requestAds
(
TEST_DATA_SPEC
,
TEST_ADS_ID
,
adViewGroup
);
imaAdsLoader
.
release
();
imaAdsLoader
.
start
(
adsMediaSource
,
TEST_DATA_SPEC
,
TEST_ADS_ID
,
adViewProvider
,
adsLoaderListener
);
...
...
@@ -253,7 +254,7 @@ public final class ImaAdsLoaderTest {
// Note: we can't currently call getContentProgress/getAdProgress as a VerifyError is thrown
// when using Robolectric and accessing VideoProgressUpdate.VIDEO_TIME_NOT_READY, due to the IMA
// SDK being proguarded.
imaAdsLoader
.
requestAds
(
TEST_DATA_SPEC
,
adViewGroup
);
imaAdsLoader
.
requestAds
(
TEST_DATA_SPEC
,
TEST_ADS_ID
,
adViewGroup
);
adEventListener
.
onAdEvent
(
getAdEvent
(
AdEventType
.
LOADED
,
mockPrerollSingleAd
));
videoAdPlayer
.
loadAd
(
TEST_AD_MEDIA_INFO
,
mockAdPodInfo
);
adEventListener
.
onAdEvent
(
getAdEvent
(
AdEventType
.
CONTENT_PAUSE_REQUESTED
,
mockPrerollSingleAd
));
...
...
@@ -300,7 +301,7 @@ public final class ImaAdsLoaderTest {
// Verify that the preroll ad has been marked as played.
assertThat
(
adsLoaderListener
.
adPlaybackState
)
.
isEqualTo
(
new
AdPlaybackState
(
/* adGroupTimesUs...= */
0
)
new
AdPlaybackState
(
TEST_ADS_ID
,
/* adGroupTimesUs...= */
0
)
.
withContentDurationUs
(
CONTENT_PERIOD_DURATION_US
)
.
withAdCount
(
/* adGroupIndex= */
0
,
/* adCount= */
1
)
.
withAdUri
(
/* adGroupIndex= */
0
,
/* adIndexInAdGroup= */
0
,
TEST_URI
)
...
...
@@ -324,7 +325,7 @@ public final class ImaAdsLoaderTest {
assertThat
(
adsLoaderListener
.
adPlaybackState
)
.
isEqualTo
(
new
AdPlaybackState
(
/* adGroupTimesUs...= */
20_500_000
)
new
AdPlaybackState
(
TEST_ADS_ID
,
/* adGroupTimesUs...= */
20_500_000
)
.
withContentDurationUs
(
CONTENT_PERIOD_DURATION_US
)
.
withAdDurationsUs
(
new
long
[][]
{{
TEST_AD_DURATION_US
}})
.
withAdCount
(
/* adGroupIndex= */
0
,
/* adCount= */
1
)
...
...
@@ -372,7 +373,7 @@ public final class ImaAdsLoaderTest {
assertThat
(
adsLoaderListener
.
adPlaybackState
)
.
isEqualTo
(
new
AdPlaybackState
(
/* adGroupTimesUs...= */
C
.
TIME_END_OF_SOURCE
)
new
AdPlaybackState
(
TEST_ADS_ID
,
/* adGroupTimesUs...= */
C
.
TIME_END_OF_SOURCE
)
.
withContentDurationUs
(
CONTENT_PERIOD_DURATION_US
)
.
withAdDurationsUs
(
new
long
[][]
{{
TEST_AD_DURATION_US
}})
.
withAdCount
(
/* adGroupIndex= */
0
,
/* adCount= */
1
)
...
...
@@ -400,7 +401,7 @@ public final class ImaAdsLoaderTest {
assertThat
(
adsLoaderListener
.
adPlaybackState
)
.
isEqualTo
(
ImaUtil
.
getInitialAdPlaybackStateForCuePoints
(
cuePoints
)
new
AdPlaybackState
(
TEST_ADS_ID
,
getAdGroupTimesUsForCuePoints
(
cuePoints
)
)
.
withContentDurationUs
(
CONTENT_PERIOD_DURATION_US
));
}
...
...
@@ -425,7 +426,7 @@ public final class ImaAdsLoaderTest {
assertThat
(
adsLoaderListener
.
adPlaybackState
)
.
isEqualTo
(
ImaUtil
.
getInitialAdPlaybackStateForCuePoints
(
cuePoints
)
new
AdPlaybackState
(
TEST_ADS_ID
,
getAdGroupTimesUsForCuePoints
(
cuePoints
)
)
.
withContentDurationUs
(
CONTENT_PERIOD_DURATION_US
)
.
withAdDurationsUs
(
new
long
[][]
{{
TEST_AD_DURATION_US
}})
.
withAdCount
(
/* adGroupIndex= */
0
,
/* adCount= */
1
)
...
...
@@ -448,7 +449,7 @@ public final class ImaAdsLoaderTest {
verify
(
mockAdsRenderingSettings
,
never
()).
setPlayAdsAfterTime
(
anyDouble
());
assertThat
(
adsLoaderListener
.
adPlaybackState
)
.
isEqualTo
(
ImaUtil
.
getInitialAdPlaybackStateForCuePoints
(
cuePoints
)
new
AdPlaybackState
(
TEST_ADS_ID
,
getAdGroupTimesUsForCuePoints
(
cuePoints
)
)
.
withContentDurationUs
(
CONTENT_PERIOD_DURATION_US
));
}
...
...
@@ -473,7 +474,7 @@ public final class ImaAdsLoaderTest {
.
of
(
expectedPlayAdsAfterTimeUs
/
C
.
MICROS_PER_SECOND
);
assertThat
(
adsLoaderListener
.
adPlaybackState
)
.
isEqualTo
(
ImaUtil
.
getInitialAdPlaybackStateForCuePoints
(
cuePoints
)
new
AdPlaybackState
(
TEST_ADS_ID
,
getAdGroupTimesUsForCuePoints
(
cuePoints
)
)
.
withContentDurationUs
(
CONTENT_PERIOD_DURATION_US
)
.
withSkippedAdGroup
(
/* adGroupIndex= */
0
));
}
...
...
@@ -499,7 +500,7 @@ public final class ImaAdsLoaderTest {
.
of
(
expectedPlayAdsAfterTimeUs
/
C
.
MICROS_PER_SECOND
);
assertThat
(
adsLoaderListener
.
adPlaybackState
)
.
isEqualTo
(
ImaUtil
.
getInitialAdPlaybackStateForCuePoints
(
cuePoints
)
new
AdPlaybackState
(
TEST_ADS_ID
,
getAdGroupTimesUsForCuePoints
(
cuePoints
)
)
.
withContentDurationUs
(
CONTENT_PERIOD_DURATION_US
)
.
withSkippedAdGroup
(
/* adGroupIndex= */
0
));
}
...
...
@@ -527,7 +528,7 @@ public final class ImaAdsLoaderTest {
verify
(
mockAdsRenderingSettings
,
never
()).
setPlayAdsAfterTime
(
anyDouble
());
assertThat
(
adsLoaderListener
.
adPlaybackState
)
.
isEqualTo
(
ImaUtil
.
getInitialAdPlaybackStateForCuePoints
(
cuePoints
)
new
AdPlaybackState
(
TEST_ADS_ID
,
getAdGroupTimesUsForCuePoints
(
cuePoints
)
)
.
withContentDurationUs
(
CONTENT_PERIOD_DURATION_US
));
}
...
...
@@ -559,7 +560,7 @@ public final class ImaAdsLoaderTest {
.
of
(
expectedPlayAdsAfterTimeUs
/
C
.
MICROS_PER_SECOND
);
assertThat
(
adsLoaderListener
.
adPlaybackState
)
.
isEqualTo
(
ImaUtil
.
getInitialAdPlaybackStateForCuePoints
(
cuePoints
)
new
AdPlaybackState
(
TEST_ADS_ID
,
getAdGroupTimesUsForCuePoints
(
cuePoints
)
)
.
withContentDurationUs
(
CONTENT_PERIOD_DURATION_US
)
.
withSkippedAdGroup
(
/* adGroupIndex= */
0
));
}
...
...
@@ -594,7 +595,7 @@ public final class ImaAdsLoaderTest {
.
of
(
expectedPlayAdsAfterTimeUs
/
C
.
MICROS_PER_SECOND
);
assertThat
(
adsLoaderListener
.
adPlaybackState
)
.
isEqualTo
(
ImaUtil
.
getInitialAdPlaybackStateForCuePoints
(
cuePoints
)
new
AdPlaybackState
(
TEST_ADS_ID
,
getAdGroupTimesUsForCuePoints
(
cuePoints
)
)
.
withSkippedAdGroup
(
/* adGroupIndex= */
0
)
.
withContentDurationUs
(
CONTENT_PERIOD_DURATION_US
));
}
...
...
@@ -629,7 +630,7 @@ public final class ImaAdsLoaderTest {
.
of
(
expectedPlayAdsAfterTimeUs
/
C
.
MICROS_PER_SECOND
);
assertThat
(
adsLoaderListener
.
adPlaybackState
)
.
isEqualTo
(
ImaUtil
.
getInitialAdPlaybackStateForCuePoints
(
cuePoints
)
new
AdPlaybackState
(
TEST_ADS_ID
,
getAdGroupTimesUsForCuePoints
(
cuePoints
)
)
.
withContentDurationUs
(
CONTENT_PERIOD_DURATION_US
)
.
withSkippedAdGroup
(
/* adGroupIndex= */
0
));
}
...
...
@@ -659,7 +660,7 @@ public final class ImaAdsLoaderTest {
verify
(
mockAdsManager
).
destroy
();
assertThat
(
adsLoaderListener
.
adPlaybackState
)
.
isEqualTo
(
ImaUtil
.
getInitialAdPlaybackStateForCuePoints
(
cuePoints
)
new
AdPlaybackState
(
TEST_ADS_ID
,
getAdGroupTimesUsForCuePoints
(
cuePoints
)
)
.
withContentDurationUs
(
CONTENT_PERIOD_DURATION_US
)
.
withSkippedAdGroup
(
/* adGroupIndex= */
0
)
.
withSkippedAdGroup
(
/* adGroupIndex= */
1
));
...
...
@@ -703,7 +704,7 @@ public final class ImaAdsLoaderTest {
.
of
(
expectedPlayAdsAfterTimeUs
/
C
.
MICROS_PER_SECOND
);
assertThat
(
adsLoaderListener
.
adPlaybackState
)
.
isEqualTo
(
ImaUtil
.
getInitialAdPlaybackStateForCuePoints
(
cuePoints
)
new
AdPlaybackState
(
TEST_ADS_ID
,
getAdGroupTimesUsForCuePoints
(
cuePoints
)
)
.
withSkippedAdGroup
(
/* adGroupIndex= */
0
)
.
withContentDurationUs
(
CONTENT_PERIOD_DURATION_US
));
}
...
...
@@ -745,7 +746,7 @@ public final class ImaAdsLoaderTest {
.
of
(
expectedPlayAdsAfterTimeUs
/
C
.
MICROS_PER_SECOND
);
assertThat
(
adsLoaderListener
.
adPlaybackState
)
.
isEqualTo
(
ImaUtil
.
getInitialAdPlaybackStateForCuePoints
(
cuePoints
)
new
AdPlaybackState
(
TEST_ADS_ID
,
getAdGroupTimesUsForCuePoints
(
cuePoints
)
)
.
withContentDurationUs
(
CONTENT_PERIOD_DURATION_US
)
.
withSkippedAdGroup
(
/* adGroupIndex= */
0
));
}
...
...
@@ -835,7 +836,7 @@ public final class ImaAdsLoaderTest {
setupPlayback
(
CONTENT_TIMELINE
,
PREROLL_CUE_POINTS_SECONDS
);
imaAdsLoader
.
start
(
adsMediaSource
,
TEST_DATA_SPEC
,
TEST_ADS_ID
,
adViewProvider
,
adsLoaderListener
);
imaAdsLoader
.
requestAds
(
TEST_DATA_SPEC
,
adViewGroup
);
imaAdsLoader
.
requestAds
(
TEST_DATA_SPEC
,
TEST_ADS_ID
,
adViewGroup
);
imaAdsLoader
.
stop
(
adsMediaSource
);
InOrder
inOrder
=
inOrder
(
mockAdDisplayContainer
);
...
...
@@ -887,7 +888,7 @@ public final class ImaAdsLoaderTest {
assertThat
(
adsLoaderListener
.
adPlaybackState
)
.
isEqualTo
(
ImaUtil
.
getInitialAdPlaybackStateForCuePoints
(
cuePoints
)
new
AdPlaybackState
(
TEST_ADS_ID
,
getAdGroupTimesUsForCuePoints
(
cuePoints
)
)
.
withContentDurationUs
(
CONTENT_PERIOD_DURATION_US
)
.
withAdCount
(
/* adGroupIndex= */
0
,
/* adCount= */
1
)
.
withAdUri
(
/* adGroupIndex= */
0
,
/* adIndexInAdGroup= */
0
,
TEST_URI
)
...
...
library/core/src/main/java/com/google/android/exoplayer2/Timeline.java
View file @
764e5e81
...
...
@@ -519,9 +519,13 @@ public abstract class Timeline {
return
positionInWindowUs
;
}
/**
* Returns the number of ad groups in the period.
*/
/** Returns the opaque identifier for ads played with this period, or {@code null} if unset. */
@Nullable
public
Object
getAdsId
()
{
return
adPlaybackState
.
adsId
;
}
/** Returns the number of ad groups in the period. */
public
int
getAdGroupCount
()
{
return
adPlaybackState
.
adGroupCount
;
}
...
...
library/core/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java
View file @
764e5e81
...
...
@@ -258,7 +258,18 @@ public final class AdPlaybackState {
public
static
final
int
AD_STATE_ERROR
=
4
;
/** Ad playback state with no ads. */
public
static
final
AdPlaybackState
NONE
=
new
AdPlaybackState
();
public
static
final
AdPlaybackState
NONE
=
new
AdPlaybackState
(
/* adsId= */
null
,
/* adGroupTimesUs= */
new
long
[
0
],
/* adGroups= */
null
,
/* adResumePositionUs= */
0L
,
/* contentDurationUs= */
C
.
TIME_UNSET
);
/**
* The opaque identifier for ads with which this instance is associated, or {@code null} if unset.
*/
@Nullable
public
final
Object
adsId
;
/** The number of ad groups. */
public
final
int
adGroupCount
;
...
...
@@ -280,29 +291,38 @@ public final class AdPlaybackState {
/**
* Creates a new ad playback state with the specified ad group times.
*
* @param adsId The opaque identifier for ads with which this instance is associated.
* @param adGroupTimesUs The times of ad groups in microseconds, relative to the start of the
* {@link com.google.android.exoplayer2.Timeline.Period} they belong to. A final element with
* the value {@link C#TIME_END_OF_SOURCE} indicates that there is a postroll ad.
*/
public
AdPlaybackState
(
long
...
adGroupTimesUs
)
{
int
count
=
adGroupTimesUs
.
length
;
adGroupCount
=
count
;
this
.
adGroupTimesUs
=
Arrays
.
copyOf
(
adGroupTimesUs
,
count
);
this
.
adGroups
=
new
AdGroup
[
count
];
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
adGroups
[
i
]
=
new
AdGroup
();
}
adResumePositionUs
=
0
;
contentDurationUs
=
C
.
TIME_UNSET
;
public
AdPlaybackState
(
Object
adsId
,
long
...
adGroupTimesUs
)
{
this
(
adsId
,
adGroupTimesUs
,
/* adGroups= */
null
,
/* adResumePositionUs= */
0
,
/* contentDurationUs= */
C
.
TIME_UNSET
);
}
private
AdPlaybackState
(
long
[]
adGroupTimesUs
,
AdGroup
[]
adGroups
,
long
adResumePositionUs
,
long
contentDurationUs
)
{
adGroupCount
=
adGroups
.
length
;
@Nullable
Object
adsId
,
long
[]
adGroupTimesUs
,
@Nullable
AdGroup
[]
adGroups
,
long
adResumePositionUs
,
long
contentDurationUs
)
{
this
.
adsId
=
adsId
;
this
.
adGroupTimesUs
=
adGroupTimesUs
;
this
.
adGroups
=
adGroups
;
this
.
adResumePositionUs
=
adResumePositionUs
;
this
.
contentDurationUs
=
contentDurationUs
;
adGroupCount
=
adGroupTimesUs
.
length
;
if
(
adGroups
==
null
)
{
adGroups
=
new
AdGroup
[
adGroupCount
];
for
(
int
i
=
0
;
i
<
adGroupCount
;
i
++)
{
adGroups
[
i
]
=
new
AdGroup
();
}
}
this
.
adGroups
=
adGroups
;
}
/**
...
...
@@ -378,7 +398,8 @@ public final class AdPlaybackState {
}
AdGroup
[]
adGroups
=
Util
.
nullSafeArrayCopy
(
this
.
adGroups
,
this
.
adGroups
.
length
);
adGroups
[
adGroupIndex
]
=
this
.
adGroups
[
adGroupIndex
].
withAdCount
(
adCount
);
return
new
AdPlaybackState
(
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
return
new
AdPlaybackState
(
adsId
,
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
}
/** Returns an instance with the specified ad URI. */
...
...
@@ -386,7 +407,8 @@ public final class AdPlaybackState {
public
AdPlaybackState
withAdUri
(
int
adGroupIndex
,
int
adIndexInAdGroup
,
Uri
uri
)
{
AdGroup
[]
adGroups
=
Util
.
nullSafeArrayCopy
(
this
.
adGroups
,
this
.
adGroups
.
length
);
adGroups
[
adGroupIndex
]
=
adGroups
[
adGroupIndex
].
withAdUri
(
uri
,
adIndexInAdGroup
);
return
new
AdPlaybackState
(
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
return
new
AdPlaybackState
(
adsId
,
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
}
/** Returns an instance with the specified ad marked as played. */
...
...
@@ -394,7 +416,8 @@ public final class AdPlaybackState {
public
AdPlaybackState
withPlayedAd
(
int
adGroupIndex
,
int
adIndexInAdGroup
)
{
AdGroup
[]
adGroups
=
Util
.
nullSafeArrayCopy
(
this
.
adGroups
,
this
.
adGroups
.
length
);
adGroups
[
adGroupIndex
]
=
adGroups
[
adGroupIndex
].
withAdState
(
AD_STATE_PLAYED
,
adIndexInAdGroup
);
return
new
AdPlaybackState
(
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
return
new
AdPlaybackState
(
adsId
,
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
}
/** Returns an instance with the specified ad marked as skipped. */
...
...
@@ -402,7 +425,8 @@ public final class AdPlaybackState {
public
AdPlaybackState
withSkippedAd
(
int
adGroupIndex
,
int
adIndexInAdGroup
)
{
AdGroup
[]
adGroups
=
Util
.
nullSafeArrayCopy
(
this
.
adGroups
,
this
.
adGroups
.
length
);
adGroups
[
adGroupIndex
]
=
adGroups
[
adGroupIndex
].
withAdState
(
AD_STATE_SKIPPED
,
adIndexInAdGroup
);
return
new
AdPlaybackState
(
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
return
new
AdPlaybackState
(
adsId
,
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
}
/** Returns an instance with the specified ad marked as having a load error. */
...
...
@@ -410,7 +434,8 @@ public final class AdPlaybackState {
public
AdPlaybackState
withAdLoadError
(
int
adGroupIndex
,
int
adIndexInAdGroup
)
{
AdGroup
[]
adGroups
=
Util
.
nullSafeArrayCopy
(
this
.
adGroups
,
this
.
adGroups
.
length
);
adGroups
[
adGroupIndex
]
=
adGroups
[
adGroupIndex
].
withAdState
(
AD_STATE_ERROR
,
adIndexInAdGroup
);
return
new
AdPlaybackState
(
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
return
new
AdPlaybackState
(
adsId
,
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
}
/**
...
...
@@ -421,7 +446,8 @@ public final class AdPlaybackState {
public
AdPlaybackState
withSkippedAdGroup
(
int
adGroupIndex
)
{
AdGroup
[]
adGroups
=
Util
.
nullSafeArrayCopy
(
this
.
adGroups
,
this
.
adGroups
.
length
);
adGroups
[
adGroupIndex
]
=
adGroups
[
adGroupIndex
].
withAllAdsSkipped
();
return
new
AdPlaybackState
(
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
return
new
AdPlaybackState
(
adsId
,
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
}
/** Returns an instance with the specified ad durations, in microseconds. */
...
...
@@ -431,7 +457,8 @@ public final class AdPlaybackState {
for
(
int
adGroupIndex
=
0
;
adGroupIndex
<
adGroupCount
;
adGroupIndex
++)
{
adGroups
[
adGroupIndex
]
=
adGroups
[
adGroupIndex
].
withAdDurationsUs
(
adDurationUs
[
adGroupIndex
]);
}
return
new
AdPlaybackState
(
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
return
new
AdPlaybackState
(
adsId
,
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
}
/**
...
...
@@ -443,7 +470,8 @@ public final class AdPlaybackState {
if
(
this
.
adResumePositionUs
==
adResumePositionUs
)
{
return
this
;
}
else
{
return
new
AdPlaybackState
(
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
return
new
AdPlaybackState
(
adsId
,
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
}
}
...
...
@@ -453,7 +481,8 @@ public final class AdPlaybackState {
if
(
this
.
contentDurationUs
==
contentDurationUs
)
{
return
this
;
}
else
{
return
new
AdPlaybackState
(
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
return
new
AdPlaybackState
(
adsId
,
adGroupTimesUs
,
adGroups
,
adResumePositionUs
,
contentDurationUs
);
}
}
...
...
@@ -466,7 +495,8 @@ public final class AdPlaybackState {
return
false
;
}
AdPlaybackState
that
=
(
AdPlaybackState
)
o
;
return
adGroupCount
==
that
.
adGroupCount
return
Util
.
areEqual
(
adsId
,
that
.
adsId
)
&&
adGroupCount
==
that
.
adGroupCount
&&
adResumePositionUs
==
that
.
adResumePositionUs
&&
contentDurationUs
==
that
.
contentDurationUs
&&
Arrays
.
equals
(
adGroupTimesUs
,
that
.
adGroupTimesUs
)
...
...
@@ -476,6 +506,7 @@ public final class AdPlaybackState {
@Override
public
int
hashCode
()
{
int
result
=
adGroupCount
;
result
=
31
*
result
+
(
adsId
==
null
?
0
:
adsId
.
hashCode
());
result
=
31
*
result
+
(
int
)
adResumePositionUs
;
result
=
31
*
result
+
(
int
)
contentDurationUs
;
result
=
31
*
result
+
Arrays
.
hashCode
(
adGroupTimesUs
);
...
...
@@ -486,7 +517,9 @@ public final class AdPlaybackState {
@Override
public
String
toString
()
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"AdPlaybackState(adResumePositionUs="
);
sb
.
append
(
"AdPlaybackState(adsId="
);
sb
.
append
(
adsId
);
sb
.
append
(
", adResumePositionUs="
);
sb
.
append
(
adResumePositionUs
);
sb
.
append
(
", adGroups=["
);
for
(
int
i
=
0
;
i
<
adGroups
.
length
;
i
++)
{
...
...
library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java
View file @
764e5e81
...
...
@@ -4349,7 +4349,8 @@ public final class ExoPlayerTest {
public
void
addMediaSource_whilePlayingAd_correctMasking
()
throws
Exception
{
long
contentDurationMs
=
10_000
;
long
adDurationMs
=
100_000
;
AdPlaybackState
adPlaybackState
=
new
AdPlaybackState
(
/* adGroupTimesUs...= */
0
);
AdPlaybackState
adPlaybackState
=
new
AdPlaybackState
(
/* adsId= */
new
Object
(),
/* adGroupTimesUs...= */
0
);
adPlaybackState
=
adPlaybackState
.
withAdCount
(
/* adGroupIndex= */
0
,
/* adCount= */
1
);
adPlaybackState
=
adPlaybackState
.
withAdUri
(
/* adGroupIndex= */
0
,
/* adIndexInAdGroup= */
0
,
Uri
.
EMPTY
);
...
...
@@ -4455,7 +4456,8 @@ public final class ExoPlayerTest {
public
void
seekTo_whilePlayingAd_correctMasking
()
throws
Exception
{
long
contentDurationMs
=
10_000
;
long
adDurationMs
=
4_000
;
AdPlaybackState
adPlaybackState
=
new
AdPlaybackState
(
/* adGroupTimesUs...= */
0
);
AdPlaybackState
adPlaybackState
=
new
AdPlaybackState
(
/* adsId= */
new
Object
(),
/* adGroupTimesUs...= */
0
);
adPlaybackState
=
adPlaybackState
.
withAdCount
(
/* adGroupIndex= */
0
,
/* adCount= */
1
);
adPlaybackState
=
adPlaybackState
.
withAdUri
(
/* adGroupIndex= */
0
,
/* adIndexInAdGroup= */
0
,
Uri
.
EMPTY
);
...
...
library/core/src/test/java/com/google/android/exoplayer2/MediaPeriodQueueTest.java
View file @
764e5e81
...
...
@@ -404,7 +404,8 @@ public final class MediaPeriodQueueTest {
private
void
setupAdTimeline
(
long
...
adGroupTimesUs
)
{
adPlaybackState
=
new
AdPlaybackState
(
adGroupTimesUs
).
withContentDurationUs
(
CONTENT_DURATION_US
);
new
AdPlaybackState
(
/* adsId= */
new
Object
(),
adGroupTimesUs
)
.
withContentDurationUs
(
CONTENT_DURATION_US
);
SinglePeriodAdTimeline
adTimeline
=
new
SinglePeriodAdTimeline
(
CONTENT_TIMELINE
,
adPlaybackState
);
setupTimeline
(
adTimeline
);
...
...
@@ -498,7 +499,8 @@ public final class MediaPeriodQueueTest {
private
void
updateAdPlaybackStateAndTimeline
(
long
...
adGroupTimesUs
)
{
adPlaybackState
=
new
AdPlaybackState
(
adGroupTimesUs
).
withContentDurationUs
(
CONTENT_DURATION_US
);
new
AdPlaybackState
(
/* adsId= */
new
Object
(),
adGroupTimesUs
)
.
withContentDurationUs
(
CONTENT_DURATION_US
);
updateTimeline
();
}
...
...
library/core/src/test/java/com/google/android/exoplayer2/analytics/DefaultPlaybackSessionManagerTest.java
View file @
764e5e81
...
...
@@ -419,7 +419,9 @@ public final class DefaultPlaybackSessionManagerTest {
/* isDynamic= */
false
,
/* durationUs =*/
10
*
C
.
MICROS_PER_SECOND
,
new
AdPlaybackState
(
/* adGroupTimesUs=... */
2
*
C
.
MICROS_PER_SECOND
,
5
*
C
.
MICROS_PER_SECOND
)
/* adsId= */
new
Object
(),
/* adGroupTimesUs=... */
2
*
C
.
MICROS_PER_SECOND
,
5
*
C
.
MICROS_PER_SECOND
)
.
withAdCount
(
/* adGroupIndex= */
0
,
/* adCount= */
1
)
.
withAdCount
(
/* adGroupIndex= */
1
,
/* adCount= */
1
)));
EventTime
adEventTime1
=
...
...
@@ -701,7 +703,8 @@ public final class DefaultPlaybackSessionManagerTest {
/* isSeekable= */
true
,
/* isDynamic= */
false
,
/* durationUs =*/
10
*
C
.
MICROS_PER_SECOND
,
new
AdPlaybackState
(
/* adGroupTimesUs=... */
C
.
TIME_END_OF_SOURCE
)
new
AdPlaybackState
(
/* adsId= */
new
Object
(),
/* adGroupTimesUs=... */
C
.
TIME_END_OF_SOURCE
)
.
withAdCount
(
/* adGroupIndex= */
0
,
/* adCount= */
1
)));
EventTime
adEventTime
=
createEventTime
(
...
...
@@ -903,7 +906,10 @@ public final class DefaultPlaybackSessionManagerTest {
/* isSeekable= */
true
,
/* isDynamic= */
false
,
/* durationUs =*/
10
*
C
.
MICROS_PER_SECOND
,
new
AdPlaybackState
(
/* adGroupTimesUs=... */
0
,
5
*
C
.
MICROS_PER_SECOND
)
new
AdPlaybackState
(
/* adsId= */
new
Object
(),
/* adGroupTimesUs=... */
0
,
5
*
C
.
MICROS_PER_SECOND
)
.
withAdCount
(
/* adGroupIndex= */
0
,
/* adCount= */
1
)
.
withAdCount
(
/* adGroupIndex= */
1
,
/* adCount= */
1
)));
EventTime
adEventTime1
=
...
...
@@ -983,7 +989,9 @@ public final class DefaultPlaybackSessionManagerTest {
/* isDynamic= */
false
,
/* durationUs =*/
10
*
C
.
MICROS_PER_SECOND
,
new
AdPlaybackState
(
/* adGroupTimesUs=... */
2
*
C
.
MICROS_PER_SECOND
,
5
*
C
.
MICROS_PER_SECOND
)
/* adsId= */
new
Object
(),
/* adGroupTimesUs=... */
2
*
C
.
MICROS_PER_SECOND
,
5
*
C
.
MICROS_PER_SECOND
)
.
withAdCount
(
/* adGroupIndex= */
0
,
/* adCount= */
1
)
.
withAdCount
(
/* adGroupIndex= */
1
,
/* adCount= */
1
)));
EventTime
adEventTime1
=
...
...
@@ -1032,7 +1040,10 @@ public final class DefaultPlaybackSessionManagerTest {
/* isSeekable= */
true
,
/* isDynamic= */
false
,
/* durationUs =*/
10
*
C
.
MICROS_PER_SECOND
,
new
AdPlaybackState
(
/* adGroupTimesUs=... */
0
,
5
*
C
.
MICROS_PER_SECOND
)
new
AdPlaybackState
(
/* adsId= */
new
Object
(),
/* adGroupTimesUs=... */
0
,
5
*
C
.
MICROS_PER_SECOND
)
.
withAdCount
(
/* adGroupIndex= */
0
,
/* adCount= */
1
)
.
withAdCount
(
/* adGroupIndex= */
1
,
/* adCount= */
1
)));
EventTime
adEventTime1
=
...
...
library/core/src/test/java/com/google/android/exoplayer2/source/ads/AdPlaybackStateTest.java
View file @
764e5e81
...
...
@@ -31,12 +31,13 @@ public final class AdPlaybackStateTest {
private
static
final
long
[]
TEST_AD_GROUP_TMES_US
=
new
long
[]
{
0
,
C
.
msToUs
(
10_000
)};
private
static
final
Uri
TEST_URI
=
Uri
.
EMPTY
;
private
static
final
Object
TEST_ADS_ID
=
new
Object
();
private
AdPlaybackState
state
;
@Before
public
void
setUp
()
{
state
=
new
AdPlaybackState
(
TEST_AD_GROUP_TMES_US
);
state
=
new
AdPlaybackState
(
TEST_AD
S_ID
,
TEST_AD
_GROUP_TMES_US
);
}
@Test
...
...
library/core/src/test/java/com/google/android/exoplayer2/source/ads/AdsMediaSourceTest.java
View file @
764e5e81
...
...
@@ -77,7 +77,7 @@ public final class AdsMediaSourceTest {
CONTENT_TIMELINE
.
getUidOfPeriod
(
/* periodIndex= */
0
);
private
static
final
AdPlaybackState
AD_PLAYBACK_STATE
=
new
AdPlaybackState
(
/* adGroupTimesUs...= */
0
)
new
AdPlaybackState
(
/* ad
sId= */
new
Object
(),
/* ad
GroupTimesUs...= */
0
)
.
withContentDurationUs
(
CONTENT_DURATION_US
)
.
withAdCount
(
/* adGroupIndex= */
0
,
/* adCount= */
1
)
.
withAdUri
(
/* adGroupIndex= */
0
,
/* adIndexInAdGroup= */
0
,
Uri
.
EMPTY
)
...
...
testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTimeline.java
View file @
764e5e81
...
...
@@ -246,7 +246,8 @@ public final class FakeTimeline extends Timeline {
*/
public
static
AdPlaybackState
createAdPlaybackState
(
int
adsPerAdGroup
,
long
...
adGroupTimesUs
)
{
int
adGroupCount
=
adGroupTimesUs
.
length
;
AdPlaybackState
adPlaybackState
=
new
AdPlaybackState
(
adGroupTimesUs
);
AdPlaybackState
adPlaybackState
=
new
AdPlaybackState
(
/* adsId= */
new
Object
(),
adGroupTimesUs
);
long
[][]
adDurationsUs
=
new
long
[
adGroupCount
][];
for
(
int
i
=
0
;
i
<
adGroupCount
;
i
++)
{
adPlaybackState
=
adPlaybackState
.
withAdCount
(
/* adGroupIndex= */
i
,
adsPerAdGroup
);
...
...
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