mirror of
https://github.com/androidx/media.git
synced 2025-05-16 03:59:54 +08:00
Add IMA and FLAC tests to the codebase
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=204302135
This commit is contained in:
parent
05a31dfd24
commit
a26bb350ee
17
extensions/flac/src/test/AndroidManifest.xml
Normal file
17
extensions/flac/src/test/AndroidManifest.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2016 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<manifest package="com.google.android.exoplayer2.ext.flac"/>
|
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer2.ext.flac;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
||||||
|
import com.google.android.exoplayer2.extractor.Extractor;
|
||||||
|
import com.google.android.exoplayer2.extractor.amr.AmrExtractor;
|
||||||
|
import com.google.android.exoplayer2.extractor.flv.FlvExtractor;
|
||||||
|
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
|
||||||
|
import com.google.android.exoplayer2.extractor.mp3.Mp3Extractor;
|
||||||
|
import com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor;
|
||||||
|
import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor;
|
||||||
|
import com.google.android.exoplayer2.extractor.ogg.OggExtractor;
|
||||||
|
import com.google.android.exoplayer2.extractor.ts.Ac3Extractor;
|
||||||
|
import com.google.android.exoplayer2.extractor.ts.AdtsExtractor;
|
||||||
|
import com.google.android.exoplayer2.extractor.ts.PsExtractor;
|
||||||
|
import com.google.android.exoplayer2.extractor.ts.TsExtractor;
|
||||||
|
import com.google.android.exoplayer2.extractor.wav.WavExtractor;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
|
/** Unit test for {@link DefaultExtractorsFactory}. */
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
public final class DefaultExtractorsFactoryTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateExtractors_returnExpectedClasses() {
|
||||||
|
DefaultExtractorsFactory defaultExtractorsFactory = new DefaultExtractorsFactory();
|
||||||
|
|
||||||
|
Extractor[] extractors = defaultExtractorsFactory.createExtractors();
|
||||||
|
List<Class> listCreatedExtractorClasses = new ArrayList<>();
|
||||||
|
for (Extractor extractor : extractors) {
|
||||||
|
listCreatedExtractorClasses.add(extractor.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
Class[] expectedExtractorClassses =
|
||||||
|
new Class[] {
|
||||||
|
MatroskaExtractor.class,
|
||||||
|
FragmentedMp4Extractor.class,
|
||||||
|
Mp4Extractor.class,
|
||||||
|
Mp3Extractor.class,
|
||||||
|
AdtsExtractor.class,
|
||||||
|
Ac3Extractor.class,
|
||||||
|
TsExtractor.class,
|
||||||
|
FlvExtractor.class,
|
||||||
|
OggExtractor.class,
|
||||||
|
PsExtractor.class,
|
||||||
|
WavExtractor.class,
|
||||||
|
AmrExtractor.class,
|
||||||
|
FlacExtractor.class
|
||||||
|
};
|
||||||
|
|
||||||
|
assertThat(listCreatedExtractorClasses).containsNoDuplicates();
|
||||||
|
assertThat(listCreatedExtractorClasses).containsExactlyElementsIn(expectedExtractorClassses);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
manifest=src/test/AndroidManifest.xml
|
16
extensions/ima/src/test/AndroidManifest.xml
Normal file
16
extensions/ima/src/test/AndroidManifest.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2018 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<manifest package="com.google.android.exoplayer2.ext.ima.test" />
|
@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer2.ext.ima;
|
||||||
|
|
||||||
|
import com.google.ads.interactivemedia.v3.api.Ad;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.AdPodInfo;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.UiElement;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/** A fake ad for testing. */
|
||||||
|
/* package */ final class FakeAd implements Ad {
|
||||||
|
|
||||||
|
private final boolean skippable;
|
||||||
|
private final AdPodInfo adPodInfo;
|
||||||
|
|
||||||
|
public FakeAd(boolean skippable, int podIndex, int totalAds, int adPosition) {
|
||||||
|
this.skippable = skippable;
|
||||||
|
adPodInfo =
|
||||||
|
new AdPodInfo() {
|
||||||
|
@Override
|
||||||
|
public int getTotalAds() {
|
||||||
|
return totalAds;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAdPosition() {
|
||||||
|
return adPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPodIndex() {
|
||||||
|
return podIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBumper() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getMaxDuration() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getTimeOffset() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSkippable() {
|
||||||
|
return skippable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AdPodInfo getAdPodInfo() {
|
||||||
|
return adPodInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAdId() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCreativeId() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCreativeAdId() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUniversalAdIdValue() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUniversalAdIdRegistry() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAdSystem() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getAdWrapperIds() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getAdWrapperSystems() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getAdWrapperCreativeIds() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLinear() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getSkipTimeOffset() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUiDisabled() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTitle() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getContentType() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAdvertiserName() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSurveyUrl() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDealId() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getWidth() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getHeight() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTraffickingParameters() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getDuration() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<UiElement> getUiElements() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer2.ext.ima;
|
||||||
|
|
||||||
|
import com.google.ads.interactivemedia.v3.api.AdErrorEvent.AdErrorListener;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.AdsManager;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.AdsManagerLoadedEvent;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.AdsRequest;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.ImaSdkSettings;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.StreamManager;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.StreamRequest;
|
||||||
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/** Fake {@link com.google.ads.interactivemedia.v3.api.AdsLoader} implementation for tests. */
|
||||||
|
public final class FakeAdsLoader implements com.google.ads.interactivemedia.v3.api.AdsLoader {
|
||||||
|
|
||||||
|
private final ImaSdkSettings imaSdkSettings;
|
||||||
|
private final AdsManager adsManager;
|
||||||
|
private final ArrayList<AdsLoadedListener> adsLoadedListeners;
|
||||||
|
private final ArrayList<AdErrorListener> adErrorListeners;
|
||||||
|
|
||||||
|
public FakeAdsLoader(ImaSdkSettings imaSdkSettings, AdsManager adsManager) {
|
||||||
|
this.imaSdkSettings = Assertions.checkNotNull(imaSdkSettings);
|
||||||
|
this.adsManager = Assertions.checkNotNull(adsManager);
|
||||||
|
adsLoadedListeners = new ArrayList<>();
|
||||||
|
adErrorListeners = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contentComplete() {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ImaSdkSettings getSettings() {
|
||||||
|
return imaSdkSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void requestAds(AdsRequest adsRequest) {
|
||||||
|
for (AdsLoadedListener listener : adsLoadedListeners) {
|
||||||
|
listener.onAdsManagerLoaded(
|
||||||
|
new AdsManagerLoadedEvent() {
|
||||||
|
@Override
|
||||||
|
public AdsManager getAdsManager() {
|
||||||
|
return adsManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StreamManager getStreamManager() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getUserRequestContext() {
|
||||||
|
return adsRequest.getUserRequestContext();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String requestStream(StreamRequest streamRequest) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAdsLoadedListener(AdsLoadedListener adsLoadedListener) {
|
||||||
|
adsLoadedListeners.add(adsLoadedListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeAdsLoadedListener(AdsLoadedListener adsLoadedListener) {
|
||||||
|
adsLoadedListeners.remove(adsLoadedListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAdErrorListener(AdErrorListener adErrorListener) {
|
||||||
|
adErrorListeners.add(adErrorListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeAdErrorListener(AdErrorListener adErrorListener) {
|
||||||
|
adErrorListeners.remove(adErrorListener);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer2.ext.ima;
|
||||||
|
|
||||||
|
import com.google.ads.interactivemedia.v3.api.AdDisplayContainer;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.AdsRequest;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.player.ContentProgressProvider;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/** Fake {@link AdsRequest} implementation for tests. */
|
||||||
|
public final class FakeAdsRequest implements AdsRequest {
|
||||||
|
|
||||||
|
private String adTagUrl;
|
||||||
|
private String adsResponse;
|
||||||
|
private Object userRequestContext;
|
||||||
|
private AdDisplayContainer adDisplayContainer;
|
||||||
|
private ContentProgressProvider contentProgressProvider;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAdTagUrl(String adTagUrl) {
|
||||||
|
this.adTagUrl = adTagUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAdTagUrl() {
|
||||||
|
return adTagUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setExtraParameter(String s, String s1) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExtraParameter(String s) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getExtraParameters() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUserRequestContext(Object userRequestContext) {
|
||||||
|
this.userRequestContext = userRequestContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getUserRequestContext() {
|
||||||
|
return userRequestContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AdDisplayContainer getAdDisplayContainer() {
|
||||||
|
return adDisplayContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAdDisplayContainer(AdDisplayContainer adDisplayContainer) {
|
||||||
|
this.adDisplayContainer = adDisplayContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContentProgressProvider getContentProgressProvider() {
|
||||||
|
return contentProgressProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setContentProgressProvider(ContentProgressProvider contentProgressProvider) {
|
||||||
|
this.contentProgressProvider = contentProgressProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAdsResponse() {
|
||||||
|
return adsResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAdsResponse(String adsResponse) {
|
||||||
|
this.adsResponse = adsResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAdWillAutoPlay(boolean b) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAdWillPlayMuted(boolean b) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setContentDuration(float v) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setContentKeywords(List<String> list) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setContentTitle(String s) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVastLoadTimeout(float v) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLiveStreamPrefetchSeconds(float v) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,196 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer2.ext.ima;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.Player;
|
||||||
|
import com.google.android.exoplayer2.Timeline;
|
||||||
|
import com.google.android.exoplayer2.testutil.StubExoPlayer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/** A fake player for testing content/ad playback. */
|
||||||
|
/* package */ final class FakePlayer extends StubExoPlayer {
|
||||||
|
|
||||||
|
private final ArrayList<Player.EventListener> listeners;
|
||||||
|
private final Timeline.Window window;
|
||||||
|
private final Timeline.Period period;
|
||||||
|
|
||||||
|
private boolean prepared;
|
||||||
|
private Timeline timeline;
|
||||||
|
private int state;
|
||||||
|
private boolean playWhenReady;
|
||||||
|
private long position;
|
||||||
|
private long contentPosition;
|
||||||
|
private boolean isPlayingAd;
|
||||||
|
private int adGroupIndex;
|
||||||
|
private int adIndexInAdGroup;
|
||||||
|
|
||||||
|
public FakePlayer() {
|
||||||
|
listeners = new ArrayList<>();
|
||||||
|
window = new Timeline.Window();
|
||||||
|
period = new Timeline.Period();
|
||||||
|
state = Player.STATE_IDLE;
|
||||||
|
playWhenReady = true;
|
||||||
|
timeline = Timeline.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the timeline on this fake player, which notifies listeners with the changed timeline. */
|
||||||
|
public void updateTimeline(Timeline timeline) {
|
||||||
|
for (Player.EventListener listener : listeners) {
|
||||||
|
listener.onTimelineChanged(
|
||||||
|
timeline,
|
||||||
|
null,
|
||||||
|
prepared ? TIMELINE_CHANGE_REASON_DYNAMIC : TIMELINE_CHANGE_REASON_PREPARED);
|
||||||
|
}
|
||||||
|
prepared = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the state of this player as if it were playing content at the given {@code position}. If
|
||||||
|
* an ad is currently playing, this will trigger a position discontinuity.
|
||||||
|
*/
|
||||||
|
public void setPlayingContentPosition(long position) {
|
||||||
|
boolean notify = isPlayingAd;
|
||||||
|
isPlayingAd = false;
|
||||||
|
adGroupIndex = C.INDEX_UNSET;
|
||||||
|
adIndexInAdGroup = C.INDEX_UNSET;
|
||||||
|
this.position = position;
|
||||||
|
contentPosition = position;
|
||||||
|
if (notify) {
|
||||||
|
for (Player.EventListener listener : listeners) {
|
||||||
|
listener.onPositionDiscontinuity(DISCONTINUITY_REASON_AD_INSERTION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the state of this player as if it were playing an ad with the given indices at the given
|
||||||
|
* {@code position}. If the player is playing a different ad or content, this will trigger a
|
||||||
|
* position discontinuity.
|
||||||
|
*/
|
||||||
|
public void setPlayingAdPosition(
|
||||||
|
int adGroupIndex, int adIndexInAdGroup, long position, long contentPosition) {
|
||||||
|
boolean notify = !isPlayingAd || this.adIndexInAdGroup != adIndexInAdGroup;
|
||||||
|
isPlayingAd = true;
|
||||||
|
this.adGroupIndex = adGroupIndex;
|
||||||
|
this.adIndexInAdGroup = adIndexInAdGroup;
|
||||||
|
this.position = position;
|
||||||
|
this.contentPosition = contentPosition;
|
||||||
|
if (notify) {
|
||||||
|
for (Player.EventListener listener : listeners) {
|
||||||
|
listener.onPositionDiscontinuity(DISCONTINUITY_REASON_AD_INSERTION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the state of this player with the given {@code STATE} constant. */
|
||||||
|
public void setState(int state, boolean playWhenReady) {
|
||||||
|
boolean notify = this.state != state || this.playWhenReady != playWhenReady;
|
||||||
|
this.state = state;
|
||||||
|
this.playWhenReady = playWhenReady;
|
||||||
|
if (notify) {
|
||||||
|
for (Player.EventListener listener : listeners) {
|
||||||
|
listener.onPlayerStateChanged(playWhenReady, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExoPlayer methods. Other methods are unsupported.
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addListener(Player.EventListener listener) {
|
||||||
|
listeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeListener(Player.EventListener listener) {
|
||||||
|
listeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPlaybackState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getPlayWhenReady() {
|
||||||
|
return playWhenReady;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Timeline getCurrentTimeline() {
|
||||||
|
return timeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCurrentPeriodIndex() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCurrentWindowIndex() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNextWindowIndex() {
|
||||||
|
return C.INDEX_UNSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPreviousWindowIndex() {
|
||||||
|
return C.INDEX_UNSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getDuration() {
|
||||||
|
if (timeline.isEmpty()) {
|
||||||
|
return C.INDEX_UNSET;
|
||||||
|
}
|
||||||
|
if (isPlayingAd()) {
|
||||||
|
long adDurationUs =
|
||||||
|
timeline.getPeriod(0, period).getAdDurationUs(adGroupIndex, adIndexInAdGroup);
|
||||||
|
return C.usToMs(adDurationUs);
|
||||||
|
} else {
|
||||||
|
return timeline.getWindow(getCurrentWindowIndex(), window).getDurationMs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getCurrentPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPlayingAd() {
|
||||||
|
return isPlayingAd;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCurrentAdGroupIndex() {
|
||||||
|
return adGroupIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCurrentAdIndexInAdGroup() {
|
||||||
|
return adIndexInAdGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getContentPosition() {
|
||||||
|
return contentPosition;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,272 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer2.ext.ima;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.Ad;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.AdDisplayContainer;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.AdEvent;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.AdEvent.AdEventType;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.AdsManager;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.AdsRenderingSettings;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.ImaSdkSettings;
|
||||||
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
|
import com.google.android.exoplayer2.Player;
|
||||||
|
import com.google.android.exoplayer2.Timeline;
|
||||||
|
import com.google.android.exoplayer2.source.SinglePeriodTimeline;
|
||||||
|
import com.google.android.exoplayer2.source.ads.AdPlaybackState;
|
||||||
|
import com.google.android.exoplayer2.source.ads.AdsLoader;
|
||||||
|
import com.google.android.exoplayer2.source.ads.AdsMediaSource.AdLoadException;
|
||||||
|
import com.google.android.exoplayer2.source.ads.SinglePeriodAdTimeline;
|
||||||
|
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
|
/** Test for {@link ImaAdsLoader}. */
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
public class ImaAdsLoaderTest {
|
||||||
|
|
||||||
|
private static final long CONTENT_DURATION_US = 10 * C.MICROS_PER_SECOND;
|
||||||
|
private static final Timeline CONTENT_TIMELINE =
|
||||||
|
new SinglePeriodTimeline(CONTENT_DURATION_US, /* isSeekable= */ true, /* isDynamic= */ false);
|
||||||
|
private static final Uri TEST_URI = Uri.EMPTY;
|
||||||
|
private static final long TEST_AD_DURATION_US = 5 * C.MICROS_PER_SECOND;
|
||||||
|
private static final long[][] PREROLL_ADS_DURATIONS_US = new long[][] {{TEST_AD_DURATION_US}};
|
||||||
|
private static final Float[] PREROLL_CUE_POINTS_SECONDS = new Float[] {0f};
|
||||||
|
private static final FakeAd UNSKIPPABLE_AD =
|
||||||
|
new FakeAd(/* skippable= */ false, /* podIndex= */ 0, /* totalAds= */ 1, /* adPosition= */ 1);
|
||||||
|
|
||||||
|
private @Mock ImaSdkSettings imaSdkSettings;
|
||||||
|
private @Mock AdsRenderingSettings adsRenderingSettings;
|
||||||
|
private @Mock AdDisplayContainer adDisplayContainer;
|
||||||
|
private @Mock AdsManager adsManager;
|
||||||
|
private SingletonImaFactory testImaFactory;
|
||||||
|
private ViewGroup adUiViewGroup;
|
||||||
|
private TestAdsLoaderListener adsLoaderListener;
|
||||||
|
private FakePlayer fakeExoPlayer;
|
||||||
|
private ImaAdsLoader imaAdsLoader;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
FakeAdsRequest fakeAdsRequest = new FakeAdsRequest();
|
||||||
|
FakeAdsLoader fakeAdsLoader = new FakeAdsLoader(imaSdkSettings, adsManager);
|
||||||
|
testImaFactory =
|
||||||
|
new SingletonImaFactory(
|
||||||
|
imaSdkSettings,
|
||||||
|
adsRenderingSettings,
|
||||||
|
adDisplayContainer,
|
||||||
|
fakeAdsRequest,
|
||||||
|
fakeAdsLoader);
|
||||||
|
adUiViewGroup = new FrameLayout(RuntimeEnvironment.application);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void teardown() {
|
||||||
|
if (imaAdsLoader != null) {
|
||||||
|
imaAdsLoader.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuilder_overridesPlayerType() {
|
||||||
|
when(imaSdkSettings.getPlayerType()).thenReturn("test player type");
|
||||||
|
setupPlayback(CONTENT_TIMELINE, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS);
|
||||||
|
|
||||||
|
verify(imaSdkSettings).setPlayerType("google/exo.ext.ima");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAttachPlayer_setsAdUiViewGroup() {
|
||||||
|
setupPlayback(CONTENT_TIMELINE, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS);
|
||||||
|
imaAdsLoader.attachPlayer(fakeExoPlayer, adsLoaderListener, adUiViewGroup);
|
||||||
|
|
||||||
|
verify(adDisplayContainer, atLeastOnce()).setAdContainer(adUiViewGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAttachPlayer_updatesAdPlaybackState() {
|
||||||
|
setupPlayback(CONTENT_TIMELINE, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS);
|
||||||
|
imaAdsLoader.attachPlayer(fakeExoPlayer, adsLoaderListener, adUiViewGroup);
|
||||||
|
|
||||||
|
assertThat(adsLoaderListener.adPlaybackState)
|
||||||
|
.isEqualTo(
|
||||||
|
new AdPlaybackState(/* adGroupTimesUs= */ 0)
|
||||||
|
.withAdDurationsUs(PREROLL_ADS_DURATIONS_US));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAttachAfterRelease() {
|
||||||
|
setupPlayback(CONTENT_TIMELINE, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS);
|
||||||
|
imaAdsLoader.release();
|
||||||
|
imaAdsLoader.attachPlayer(fakeExoPlayer, adsLoaderListener, adUiViewGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAttachAndCallbacksAfterRelease() {
|
||||||
|
setupPlayback(CONTENT_TIMELINE, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS);
|
||||||
|
imaAdsLoader.release();
|
||||||
|
imaAdsLoader.attachPlayer(fakeExoPlayer, adsLoaderListener, adUiViewGroup);
|
||||||
|
fakeExoPlayer.setPlayingContentPosition(/* position= */ 0);
|
||||||
|
fakeExoPlayer.setState(Player.STATE_READY, true);
|
||||||
|
|
||||||
|
// If callbacks are invoked there is no crash.
|
||||||
|
// 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(adUiViewGroup);
|
||||||
|
imaAdsLoader.onAdEvent(getAdEvent(AdEventType.LOADED, UNSKIPPABLE_AD));
|
||||||
|
imaAdsLoader.loadAd(TEST_URI.toString());
|
||||||
|
imaAdsLoader.onAdEvent(getAdEvent(AdEventType.CONTENT_PAUSE_REQUESTED, UNSKIPPABLE_AD));
|
||||||
|
imaAdsLoader.playAd();
|
||||||
|
imaAdsLoader.onAdEvent(getAdEvent(AdEventType.STARTED, UNSKIPPABLE_AD));
|
||||||
|
imaAdsLoader.pauseAd();
|
||||||
|
imaAdsLoader.stopAd();
|
||||||
|
imaAdsLoader.onPlayerError(ExoPlaybackException.createForSource(new IOException()));
|
||||||
|
imaAdsLoader.onPositionDiscontinuity(Player.DISCONTINUITY_REASON_SEEK);
|
||||||
|
imaAdsLoader.onAdEvent(getAdEvent(AdEventType.CONTENT_RESUME_REQUESTED, /* ad= */ null));
|
||||||
|
imaAdsLoader.handlePrepareError(
|
||||||
|
/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, new IOException());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPlayback_withPrerollAd_marksAdAsPlayed() {
|
||||||
|
setupPlayback(CONTENT_TIMELINE, PREROLL_ADS_DURATIONS_US, PREROLL_CUE_POINTS_SECONDS);
|
||||||
|
|
||||||
|
// Load the preroll ad.
|
||||||
|
imaAdsLoader.attachPlayer(fakeExoPlayer, adsLoaderListener, adUiViewGroup);
|
||||||
|
imaAdsLoader.onAdEvent(getAdEvent(AdEventType.LOADED, UNSKIPPABLE_AD));
|
||||||
|
imaAdsLoader.loadAd(TEST_URI.toString());
|
||||||
|
imaAdsLoader.onAdEvent(getAdEvent(AdEventType.CONTENT_PAUSE_REQUESTED, UNSKIPPABLE_AD));
|
||||||
|
|
||||||
|
// Play the preroll ad.
|
||||||
|
imaAdsLoader.playAd();
|
||||||
|
fakeExoPlayer.setPlayingAdPosition(
|
||||||
|
/* adGroupIndex= */ 0,
|
||||||
|
/* adIndexInAdGroup= */ 0,
|
||||||
|
/* position= */ 0,
|
||||||
|
/* contentPosition= */ 0);
|
||||||
|
fakeExoPlayer.setState(Player.STATE_READY, true);
|
||||||
|
imaAdsLoader.onAdEvent(getAdEvent(AdEventType.STARTED, UNSKIPPABLE_AD));
|
||||||
|
imaAdsLoader.onAdEvent(getAdEvent(AdEventType.FIRST_QUARTILE, UNSKIPPABLE_AD));
|
||||||
|
imaAdsLoader.onAdEvent(getAdEvent(AdEventType.MIDPOINT, UNSKIPPABLE_AD));
|
||||||
|
imaAdsLoader.onAdEvent(getAdEvent(AdEventType.THIRD_QUARTILE, UNSKIPPABLE_AD));
|
||||||
|
|
||||||
|
// Play the content.
|
||||||
|
fakeExoPlayer.setPlayingContentPosition(0);
|
||||||
|
imaAdsLoader.stopAd();
|
||||||
|
imaAdsLoader.onAdEvent(getAdEvent(AdEventType.CONTENT_RESUME_REQUESTED, /* ad= */ null));
|
||||||
|
|
||||||
|
// Verify that the preroll ad has been marked as played.
|
||||||
|
assertThat(adsLoaderListener.adPlaybackState)
|
||||||
|
.isEqualTo(
|
||||||
|
new AdPlaybackState(/* adGroupTimesUs= */ 0)
|
||||||
|
.withContentDurationUs(CONTENT_DURATION_US)
|
||||||
|
.withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1)
|
||||||
|
.withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, /* uri= */ TEST_URI)
|
||||||
|
.withAdDurationsUs(PREROLL_ADS_DURATIONS_US)
|
||||||
|
.withPlayedAd(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0)
|
||||||
|
.withAdResumePositionUs(/* adResumePositionUs= */ 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupPlayback(Timeline contentTimeline, long[][] adDurationsUs, Float[] cuePoints) {
|
||||||
|
fakeExoPlayer = new FakePlayer();
|
||||||
|
adsLoaderListener = new TestAdsLoaderListener(fakeExoPlayer, contentTimeline, adDurationsUs);
|
||||||
|
when(adsManager.getAdCuePoints()).thenReturn(Arrays.asList(cuePoints));
|
||||||
|
imaAdsLoader =
|
||||||
|
new ImaAdsLoader.Builder(RuntimeEnvironment.application)
|
||||||
|
.setImaFactory(testImaFactory)
|
||||||
|
.setImaSdkSettings(imaSdkSettings)
|
||||||
|
.buildForAdTag(TEST_URI);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AdEvent getAdEvent(AdEventType adEventType, @Nullable Ad ad) {
|
||||||
|
return new AdEvent() {
|
||||||
|
@Override
|
||||||
|
public AdEventType getType() {
|
||||||
|
return adEventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Ad getAd() {
|
||||||
|
return ad;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getAdData() {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Ad loader event listener that forwards ad playback state to a fake player. */
|
||||||
|
private static final class TestAdsLoaderListener implements AdsLoader.EventListener {
|
||||||
|
|
||||||
|
private final FakePlayer fakeExoPlayer;
|
||||||
|
private final Timeline contentTimeline;
|
||||||
|
private final long[][] adDurationsUs;
|
||||||
|
|
||||||
|
public AdPlaybackState adPlaybackState;
|
||||||
|
|
||||||
|
public TestAdsLoaderListener(
|
||||||
|
FakePlayer fakeExoPlayer, Timeline contentTimeline, long[][] adDurationsUs) {
|
||||||
|
this.fakeExoPlayer = fakeExoPlayer;
|
||||||
|
this.contentTimeline = contentTimeline;
|
||||||
|
this.adDurationsUs = adDurationsUs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAdPlaybackState(AdPlaybackState adPlaybackState) {
|
||||||
|
adPlaybackState = adPlaybackState.withAdDurationsUs(adDurationsUs);
|
||||||
|
this.adPlaybackState = adPlaybackState;
|
||||||
|
fakeExoPlayer.updateTimeline(new SinglePeriodAdTimeline(contentTimeline, adPlaybackState));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAdLoadError(AdLoadException error, DataSpec dataSpec) {
|
||||||
|
assertThat(error.type).isNotEqualTo(AdLoadException.TYPE_UNEXPECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAdClicked() {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAdTapped() {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer2.ext.ima;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.AdDisplayContainer;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.AdsRenderingSettings;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.AdsRequest;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.ImaSdkSettings;
|
||||||
|
|
||||||
|
/** {@link ImaAdsLoader.ImaFactory} that returns provided instances from each getter, for tests. */
|
||||||
|
final class SingletonImaFactory implements ImaAdsLoader.ImaFactory {
|
||||||
|
|
||||||
|
private final ImaSdkSettings imaSdkSettings;
|
||||||
|
private final AdsRenderingSettings adsRenderingSettings;
|
||||||
|
private final AdDisplayContainer adDisplayContainer;
|
||||||
|
private final AdsRequest adsRequest;
|
||||||
|
private final com.google.ads.interactivemedia.v3.api.AdsLoader adsLoader;
|
||||||
|
|
||||||
|
public SingletonImaFactory(
|
||||||
|
ImaSdkSettings imaSdkSettings,
|
||||||
|
AdsRenderingSettings adsRenderingSettings,
|
||||||
|
AdDisplayContainer adDisplayContainer,
|
||||||
|
AdsRequest adsRequest,
|
||||||
|
com.google.ads.interactivemedia.v3.api.AdsLoader adsLoader) {
|
||||||
|
this.imaSdkSettings = imaSdkSettings;
|
||||||
|
this.adsRenderingSettings = adsRenderingSettings;
|
||||||
|
this.adDisplayContainer = adDisplayContainer;
|
||||||
|
this.adsRequest = adsRequest;
|
||||||
|
this.adsLoader = adsLoader;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ImaSdkSettings createImaSdkSettings() {
|
||||||
|
return imaSdkSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AdsRenderingSettings createAdsRenderingSettings() {
|
||||||
|
return adsRenderingSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AdDisplayContainer createAdDisplayContainer() {
|
||||||
|
return adDisplayContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AdsRequest createAdsRequest() {
|
||||||
|
return adsRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public com.google.ads.interactivemedia.v3.api.AdsLoader createAdsLoader(
|
||||||
|
Context context, ImaSdkSettings imaSdkSettings) {
|
||||||
|
return adsLoader;
|
||||||
|
}
|
||||||
|
}
|
1
extensions/ima/src/test/resources/robolectric.properties
Normal file
1
extensions/ima/src/test/resources/robolectric.properties
Normal file
@ -0,0 +1 @@
|
|||||||
|
manifest=src/test/AndroidManifest.xml
|
Loading…
x
Reference in New Issue
Block a user