Commit 20dc5dc0 by andrewlewis Committed by Oliver Woodman

Catch exceptions in all IMA callbacks

If an exception is thrown in an IMA callback it crashes the process with lots of
logging from WebView (including several stack traces, etc.). This change wraps
ImaAdsLoader code that might throw, skips any remaining ads (as the errors are
not recoverable, in general) and notifies a new load error callback so that the
application can implement its own handling. The intention is to make the loader
robust to unexpected requests from IMA and avoid crashes.

Also handle IMA loading an ad in an ad group that has no available ads. In rare
cases IMA will try to load an ad for which an error was previously notified, so
this drops those load requests allowing playback of the content to continue.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=185985850
parent b36db1a8
......@@ -101,6 +101,7 @@
([#3715](https://github.com/google/ExoPlayer/issues/3715)).
* Propagate ad media preparation errors to IMA so that the ads can be
skipped.
* Handle exceptions in IMA callbacks so that can be logged less verbosely.
* `EventLogger` moved from the demo app into the core library.
* Fix ANR issue on the Huawei P8 Lite, Huawei Y6II, Moto C+, Meizu M5C,
Lenovo K4 Note and Sony Xperia E5.
......
......@@ -54,11 +54,19 @@ public interface AdsLoader {
void onAdPlaybackState(AdPlaybackState adPlaybackState);
/**
* Called when there was an error loading ads.
* Called when there was an error loading ads. The loader will skip the problematic ad(s).
*
* @param error The error.
*/
void onLoadError(IOException error);
void onAdLoadError(IOException error);
/**
* Called when an unexpected internal error is encountered while loading ads. The loader will
* skip all remaining ads, as the error is not recoverable.
*
* @param error The error.
*/
void onInternalAdLoadError(RuntimeException error);
/**
* Called when the user clicks through an ad (for example, following a 'learn more' link).
......
......@@ -73,15 +73,22 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
public interface EventListener extends MediaSourceEventListener {
/**
* Called if there was an error loading ads. The media source will load the content without ads
* if ads can't be loaded, so listen for this event if you need to implement additional handling
* (for example, stopping the player).
* Called if there was an error loading one or more ads. The loader will skip the problematic
* ad(s).
*
* @param error The error.
*/
void onAdLoadError(IOException error);
/**
* Called when an unexpected internal error is encountered while loading ads. The loader will
* skip all remaining ads, as the error is not recoverable.
*
* @param error The error.
*/
void onInternalAdLoadError(RuntimeException error);
/**
* Called when the user clicks through an ad (for example, following a 'learn more' link).
*/
void onAdClicked();
......@@ -418,7 +425,7 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
}
@Override
public void onLoadError(final IOException error) {
public void onAdLoadError(final IOException error) {
if (released) {
return;
}
......@@ -436,6 +443,24 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
}
}
@Override
public void onInternalAdLoadError(final RuntimeException error) {
if (released) {
return;
}
Log.w(TAG, "Internal ad load error", error);
if (eventHandler != null && eventListener != null) {
eventHandler.post(
new Runnable() {
@Override
public void run() {
if (!released) {
eventListener.onInternalAdLoadError(error);
}
}
});
}
}
}
private final class AdPrepareErrorListener implements DeferredMediaPeriod.PrepareErrorListener {
......
......@@ -383,6 +383,11 @@ public class EventLogger
}
@Override
public void onInternalAdLoadError(RuntimeException error) {
printInternalError("internalAdLoadError", error);
}
@Override
public void onAdClicked() {
// Do nothing.
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment