Skip to content
This repository has been archived by the owner on May 22, 2023. It is now read-only.

Commit

Permalink
Release: version 5.16.2
Browse files Browse the repository at this point in the history
  • Loading branch information
mopubservice committed Mar 19, 2021
1 parent f82711e commit 5dab5a0
Show file tree
Hide file tree
Showing 17 changed files with 869 additions and 131 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## Version 5.16.2 (March 18, 2021)
- **Bug Fixes**
- Handle WebViewClient#onRenderProcessGone for API 26+ devices regarding the VAST icon WebView so WebView crashes do not take the entire process with it.
- Fix rewarded video duration calculation.
- Fix rare `InvalidStateException` when finishing a VAST video with a companion image.
- Fix `UnsupportedOperationException` caused by non-hierarchical URIs.

## Version 5.16.0 (February 16, 2021)
- **Features**
- Add support for rewarded display ads and rewarded ads with rich media end cards. See [Integration Steps](https://developers.mopub.com/publishers/android/rewarded-ad/).
Expand Down
24 changes: 9 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Sign up for an account at [http://app.mopub.com/](http://app.mopub.com/).

## Need Help?

You can find integration documentation on our [wiki](https://github.com/mopub/mopub-android-sdk/wiki/Getting-Started) and additional help documentation on our [developer help site](http://dev.twitter.com/mopub).
You can find integration documentation on our [wiki](https://github.com/mopub/mopub-android-sdk/wiki/Getting-Started) and additional help documentation on our [developer help site](https://developers.mopub.com/publishers/android/).

To file an issue with our team visit the [MoPub Forum](https://twittercommunity.com/c/advertiser-api/mopub) or email [support@mopub.com](mailto:support@mopub.com).

Expand All @@ -30,7 +30,7 @@ The MoPub SDK is available via:
}
dependencies {
implementation('com.mopub:mopub-sdk:5.16.0@aar') {
implementation('com.mopub:mopub-sdk:5.16.2@aar') {
transitive = true
}
}
Expand All @@ -51,17 +51,17 @@ The MoPub SDK is available via:
// ... other project dependencies
// For banners
implementation('com.mopub:mopub-sdk-banner:5.16.0@aar') {
implementation('com.mopub:mopub-sdk-banner:5.16.2@aar') {
transitive = true
}
// For interstitials and rewarded ads
implementation('com.mopub:mopub-sdk-fullscreen:5.16.0@aar') {
implementation('com.mopub:mopub-sdk-fullscreen:5.16.2@aar') {
transitive = true
}
// For native static (images).
implementation('com.mopub:mopub-sdk-native-static:5.16.0@aar') {
implementation('com.mopub:mopub-sdk-native-static:5.16.2@aar') {
transitive = true
}
}
Expand Down Expand Up @@ -90,18 +90,12 @@ The MoPub SDK is available via:
Please view the [changelog](https://github.com/mopub/mopub-android-sdk/blob/master/CHANGELOG.md) for a complete list of additions, fixes, and enhancements in the latest release.
- **Features**
- Add support for rewarded display ads and rewarded ads with rich media end cards. See [Integration Steps](https://developers.mopub.com/publishers/android/rewarded-ad/).
- Rename `MoPubRewardedVideos` to `MoPubRewardedAds` and `MoPubRewardedVideoListener` to `MoPubRewardedAdListener`. See the [API Reference](https://developers.mopub.com/publishers/reference/android/MoPub/) for more details.
- Add 5G cellular support.
- Update AndroidX Media2 dependencies from version 1.0.1 to 1.1.1.
- **Bug Fixes**
- Fix crash when adding a theme to native recycler view layout.
- Fix memory leak when destroy is called on a fullscreen ad.
- Fix rotation for ads without an orientation specified.
- Fix rewarded ads being playable after they have expired.
- Address clickability issues with image and rewarded ads.
- Address `MoPubRewardedVideos.hasRewardedVideo()` returning the wrong value in certain instances.
- Handle WebViewClient#onRenderProcessGone for API 26+ devices regarding the VAST icon WebView so WebView crashes do not take the entire process with it.
- Fix rewarded video duration calculation.
- Fix rare `InvalidStateException` when finishing a VAST video with a companion image.
- Fix `UnsupportedOperationException` caused by non-hierarchical URIs.
## Requirements
Expand Down
4 changes: 2 additions & 2 deletions mopub-sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android-extensions'

project.group = 'com.mopub'
project.description = '''MoPub Sample App'''
project.version = '5.16.0'
project.version = '5.16.2'

android {
compileSdkVersion 30
Expand All @@ -42,7 +42,7 @@ android {
}

defaultConfig {
versionCode 84
versionCode 86
versionName version
minSdkVersion 19
targetSdkVersion 30
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import static com.mopub.common.logging.MoPubLog.SdkLogEvent.INIT_STARTED;

public class MoPub {
public static final String SDK_VERSION = "5.16.0";
public static final String SDK_VERSION = "5.16.2";

public enum LocationAwareness { NORMAL, TRUNCATED, DISABLED }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ protected void performAction(
/* 4 */ OPEN_APP_MARKET(true) {
@Override
public boolean shouldTryHandlingUrl(@NonNull final Uri uri) {
if (!uri.isHierarchical()) {
return false; // we only support hierarchical URIs for OPEN_APP_MARKET
}

final String scheme = uri.getScheme();
final String host = uri.getHost();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.util.Patterns;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
Expand Down Expand Up @@ -90,8 +91,11 @@ public final void fillContent(@NonNull final String htmlData,
listener.onReady(mWebView);
}

String htmlDataOm = ViewabilityManager.injectVerificationUrlsIntoHtml(htmlData, viewabilityVendors);
htmlDataOm = ViewabilityManager.injectScriptContentIntoHtml(htmlDataOm);
String htmlDataOm = htmlData;
if (!Patterns.WEB_URL.matcher(htmlData).matches()) {
htmlDataOm = ViewabilityManager.injectVerificationUrlsIntoHtml(htmlData, viewabilityVendors);
htmlDataOm = ViewabilityManager.injectScriptContentIntoHtml(htmlDataOm);
}

doFillContent(htmlDataOm);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,25 @@ class VastResource(
*/
fun initializeWebView(webView: VastWebView) {
webView.run {
getResourceValue()?.let { loadData(it) }
getHtmlResourceValue()?.let { loadData(it) }
}
}

/**
* Gets the HTML necessary to show the creative type or the url where it exists.
*/
fun getResourceValue(): String? {
fun getHtmlResourceValue(): String? {
return when {
type == Type.HTML_RESOURCE -> resource
type == Type.IFRAME_RESOURCE -> "<iframe frameborder=\"0\" scrolling=\"no\" " +
"marginheight=\"0\" marginwidth=\"0\" style=\"border: 0px; margin: 0px;\"" +
" width=\"${this@VastResource.width}\"" +
" height=\"${this@VastResource.height}\"" +
" src=\"$resource\"></iframe>"
type == Type.STATIC_RESOURCE && creativeType == CreativeType.IMAGE -> resource
type == Type.STATIC_RESOURCE && creativeType == CreativeType.IMAGE -> "<html>" +
"<head></head><body style=\"margin:0;padding:0\"><img src=\"$resource\"" +
" width=\"100%\" style=\"max-width:100%;max-height:100%;\" />" +
"</body></html>"
type == Type.STATIC_RESOURCE && creativeType == CreativeType.JAVASCRIPT ->
"<script src=\"$resource\"></script>"
type == Type.BLURRED_LAST_FRAME -> resource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import android.content.res.Configuration
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
Expand All @@ -22,9 +23,11 @@ import android.view.View.INVISIBLE
import android.view.View.OnTouchListener
import android.view.View.VISIBLE
import android.view.View.generateViewId
import android.webkit.RenderProcessGoneDetail
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.RelativeLayout
import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import androidx.media.AudioAttributesCompat
import androidx.media2.common.SessionPlayer
Expand Down Expand Up @@ -85,7 +88,7 @@ class VastVideoViewController(
val vastIconConfig: VastIconConfig?
private val externalViewabilitySessionManager = ExternalViewabilitySessionManager.create()
@VisibleForTesting
val iconView: View
lateinit var iconView: View

private val progressCheckerRunnable: VastVideoViewProgressRunnable
private val countdownRunnable: VastVideoViewCountdownRunnable
Expand Down Expand Up @@ -255,48 +258,6 @@ class VastVideoViewController(
it.setOnClickListener{ }
}

iconView = vastIconConfig?.let { iconConfig ->
VastWebView.createView(context, iconConfig.vastResource).also {
it.vastWebViewClickListener = VastWebView.VastWebViewClickListener {
makeVastTrackingHttpRequest(
iconConfig.clickTrackingUris,
null,
getCurrentPosition(),
networkMediaFileUrl,
context
)
vastIconConfig?.handleClick(context, null, vastVideoConfig.dspCreativeId)
}
it.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView,
url: String
): Boolean {
vastIconConfig?.handleClick(
context,
url,
vastVideoConfig.dspCreativeId
)
return true
}
}
it.visibility = INVISIBLE
val layoutParams = vastIconConfig?.let {
iconConfig
RelativeLayout.LayoutParams(
Dips.asIntPixels(iconConfig.width.toFloat(), context),
Dips.asIntPixels(iconConfig.height.toFloat(), context)
)
}
val leftMargin = Dips.dipsToIntPixels(LEFT_MARGIN_DIPS.toFloat(), context)
val topMargin = Dips.dipsToIntPixels(TOP_MARGIN_DIPS.toFloat(), context)
layoutParams?.setMargins(leftMargin, topMargin, 0, 0)

layout.addView(it, layoutParams)
externalViewabilitySessionManager.registerVideoObstruction(it, ViewabilityObstruction.INDUSTRY_ICON)
}
} ?: View(context)

ctaButtonWidget = VideoCtaButtonWidget(
context,
hasCompanionAd,
Expand Down Expand Up @@ -353,6 +314,8 @@ class VastVideoViewController(
if (vastVideoConfig.isRewarded) {
showCloseButtonDelay = if (hasCompanionAd) {
vastVideoConfig.countdownTimerDuration
} else if (videoDuration > vastVideoConfig.countdownTimerDuration){
vastVideoConfig.countdownTimerDuration
} else {
videoDuration
}
Expand Down Expand Up @@ -545,7 +508,7 @@ class VastVideoViewController(
/**
* Displays and impresses the icon if the current position of the video is greater than the
* offset of the icon. Once the current position is greater than the offset plus duration, the
* icon is then hidden again.
* icon is then hidden again. We intentionally do not preload the icon.
*
* @param currentPosition the current position of the video in milliseconds.
*/
Expand All @@ -555,14 +518,76 @@ class VastVideoViewController(
return
}

iconView.visibility = VISIBLE
if (!::iconView.isInitialized) {
iconView = vastIconConfig?.let { iconConfig ->
VastWebView.createView(context, iconConfig.vastResource).also {
it.vastWebViewClickListener = VastWebView.VastWebViewClickListener {
makeVastTrackingHttpRequest(
iconConfig.clickTrackingUris,
null,
getCurrentPosition(),
networkMediaFileUrl,
context
)
vastIconConfig?.handleClick(context, null, vastVideoConfig.dspCreativeId)
}
it.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView,
url: String
): Boolean {
vastIconConfig?.handleClick(
context,
url,
vastVideoConfig.dspCreativeId
)
return true
}

@RequiresApi(Build.VERSION_CODES.O)
override fun onRenderProcessGone(
view: WebView?,
detail: RenderProcessGoneDetail?
): Boolean {
MoPubLog.log(
CUSTOM,
"onRenderProcessGone() called from the IconView. Ignoring the icon."
)
vastVideoConfig.handleError(
context,
VastErrorCode.UNDEFINED_ERROR,
getCurrentPosition()
)
return true
}
}
val layoutParams = vastIconConfig?.let {
RelativeLayout.LayoutParams(
Dips.asIntPixels(iconConfig.width.toFloat(), context),
Dips.asIntPixels(iconConfig.height.toFloat(), context)
)
}
val leftMargin = Dips.dipsToIntPixels(LEFT_MARGIN_DIPS.toFloat(), context)
val topMargin = Dips.dipsToIntPixels(TOP_MARGIN_DIPS.toFloat(), context)
layoutParams?.setMargins(leftMargin, topMargin, 0, 0)

layout.addView(it, layoutParams)
externalViewabilitySessionManager.registerVideoObstruction(
it,
ViewabilityObstruction.INDUSTRY_ICON
)
}
} ?: View(context)
iconView.visibility = VISIBLE
}

networkMediaFileUrl?.let {
vastIconConfig?.handleImpression(context, currentPosition, it)
}

val durationMS = vastIconConfig?.durationMS ?: return

if (currentPosition >= offsetMs + durationMS) {
if (currentPosition >= offsetMs + durationMS && ::iconView.isInitialized) {
iconView.visibility = GONE
}
}
Expand Down Expand Up @@ -655,7 +680,9 @@ class VastVideoViewController(

videoView.visibility = INVISIBLE
progressBarWidget.visibility = GONE
iconView.visibility = GONE
if (::iconView.isInitialized) {
iconView.visibility = GONE
}

topGradientStripWidget.notifyVideoComplete()
bottomGradientStripWidget.notifyVideoComplete()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import android.net.Uri;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Patterns;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
Expand Down Expand Up @@ -929,6 +930,10 @@ protected void doFillContent(@NonNull String htmlData) {
mDefaultAdContainer.addView(mWebView,
new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

if (Patterns.WEB_URL.matcher(htmlData).matches()) {
mMraidBridge.setContentUrl(htmlData);
return;
}
mMraidBridge.setContentHtml(htmlData);
}

Expand Down
Loading

0 comments on commit 5dab5a0

Please sign in to comment.