Skip to content

Commit

Permalink
Pull request #718: Release branch v8.8
Browse files Browse the repository at this point in the history
Merge in MOBILE-SDK/app_mobile-sdk-android from release_branch_v8.8 to master

* commit 'd1d1b6697e5d48d0d8a95e56865bbaf1a951accf':
  release version 8.8
  Pull request #715: LazyLoading for NativeAssembly
  Pull request #716: added additional information for invalid response errors
  • Loading branch information
Ritesh Zaveri committed Aug 22, 2023
2 parents 5a3f691 + d1d1b66 commit df71129
Show file tree
Hide file tree
Showing 13 changed files with 162 additions and 20 deletions.
8 changes: 8 additions & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 8.8

### New Features
+ MS-5349 Enabled lazy loading for banner native rendering

### Improvement/Bug Fixes
+ MS-5371 Added additional information for INVALID_REQUEST code error messages

## 8.7

### New Features
Expand Down
3 changes: 2 additions & 1 deletion extras/AndroidAdvertisingID/project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
# To enable ProGuard to shrink and obfuscate your
# code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

android.library=true
Expand Down
4 changes: 2 additions & 2 deletions instreamvideo/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Project Properties
version = "1.46" // Instream SDK version
version = "1.47" // Instream SDK version

apply plugin: 'com.android.library'

Expand All @@ -10,7 +10,7 @@ android {
defaultConfig {
minSdkVersion 14
targetSdkVersion 32
versionCode 45 // An integer value that represents the version of the code, relative to other versions. Increase for each release.
versionCode 46 // An integer value that represents the version of the code, relative to other versions. Increase for each release.
versionName version
consumerProguardFiles 'proguard-project.txt'
}
Expand Down
4 changes: 2 additions & 2 deletions sdk/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Project properties
version = "8.7"
version = "8.8"
group='com.appnexus.opensdk'

// Android build
Expand All @@ -10,7 +10,7 @@ android {
buildToolsVersion '32.0.0'

defaultConfig {
versionCode 104 // An integer value that represents the version of the code, relative to other versions. Increase for each release.
versionCode 105 // An integer value that represents the version of the code, relative to other versions. Increase for each release.
versionName version
consumerProguardFiles 'proguard-project.txt'
minSdkVersion 14
Expand Down
2 changes: 1 addition & 1 deletion sdk/res/values/errors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@
<string formatted="false" name="apn_load_webview_failure_is_not_lazy_load">loadLazyAd() failed, the Ad isn\'t lazy loaded yet.</string>
<string formatted="false" name="apn_enable_lazy_webview_failure_request_in_progress">enableLazyLoad() failed, AdRequest is already in progress.</string>
<string formatted="false" name="apn_enable_lazy_webview_failure_already_enabled">enableLazyLoad() failed, Already enabled once.</string>
<string formatted="false" name="apn_enable_lazy_webview_failure_non_banner">loadLazyAd() failed, loadLazyAd can be applied only to the Banner Ad Type.</string>
<string formatted="false" name="apn_enable_lazy_webview_failure_non_banner">loadLazyAd() failed, loadLazyAd can be applied only to the Banner or Native Assembly Ad Type.</string>
<string formatted="false" name="request_manager_owner_error">Request Manager can\'t proceed as it has <t></t>wo initialized owners</string>
<string formatted="false" name="passed_context_error">Ad Request can\'t proceed without Activity Context</string>
</resources>
8 changes: 7 additions & 1 deletion sdk/src/com/appnexus/opensdk/AdFetcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,12 @@ synchronized public void handleMessage(Message msg) {
Clog.w(Clog.lazyLoadLogTag, "Not Fetching due to Lazy Load");
return;
}

// Condition to restrict the Auto Refresh if the AdType is not AdType.BANNER.
if (fetcher.owner != null && fetcher.owner instanceof AdView && ((AdView)fetcher.owner).getAdResponseInfo() != null && ((AdView)fetcher.owner).getAdResponseInfo().getAdType() != AdType.BANNER) {
Clog.w(Clog.baseLogTag, "Not Fetching due to AdType is not BANNER");
return;
}
}
// Checks if the lazy load is enabled and de activates the Webview (activateWebview - boolean in the AdView), so that the AutoRefresh for Lazy Load can work.
// Doing this will deActivate the Webview, which will be required to be activated by calling the loadLazyAd() later.
Expand Down Expand Up @@ -280,7 +286,7 @@ synchronized public void handleMessage(Message msg) {
fetcher.requestManager = new AdViewRequestManager(fetcher.owner);
fetcher.requestManager.execute();
} else {
fetcher.owner.getAdDispatcher().onAdFailed(ResultCode.getNewInstance(ResultCode.INVALID_REQUEST), null);
fetcher.owner.getAdDispatcher().onAdFailed(ResultCode.getNewInstance(ResultCode.INVALID_REQUEST, "Media type unknown"), null);
}
}
}
Expand Down
23 changes: 20 additions & 3 deletions sdk/src/com/appnexus/opensdk/AdView.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ public abstract class AdView extends FrameLayout implements Ad, MultiAd, Visibil
*/
protected boolean isAdResponseReceived = false;

/**
* This boolean keeps track, if the NativeAdResponse returned from impbus has a valid Native Renderer URL
* and is eligible to be displayed as a Banner Native Assembly Renderer Ad.
*/
protected boolean eligibleForNativeAssemblyRendering = false;

/**
* Begin Construction
*/
Expand Down Expand Up @@ -1061,6 +1067,7 @@ public void run() {

private void processAdLoaded(AdResponse ad) {
isFetching = false;
eligibleForNativeAssemblyRendering = false;
if (ad.getMediaType() == MediaType.BANNER || ad.getMediaType() == MediaType.INTERSTITIAL) {
handleBannerOrInterstitialAd(ad);
} else if (ad.getMediaType() == MediaType.NATIVE) {
Expand Down Expand Up @@ -1092,6 +1099,7 @@ public void run() {

private void processAdFailed(final ResultCode code, final ANAdResponseInfo adResponseInfo) {
isFetching = false;
eligibleForNativeAssemblyRendering = false;
handler.post(new Runnable() {
@Override
public void run() {
Expand Down Expand Up @@ -1190,6 +1198,7 @@ public void run() {
public void onAdResponseReceived() {
Clog.d(Clog.baseLogTag, "onAdResponseReceived");
isAdResponseReceived = true;
eligibleForNativeAssemblyRendering = false;
}

private void handleNativeAd(AdResponse ad) {
Expand Down Expand Up @@ -1596,8 +1605,8 @@ protected boolean loadLazyAd() {
return false;
}

// loadLazyAd() only if the AdType is AdType.BANNER
if (getAdResponseInfo().getAdType() != AdType.BANNER) {
// loadLazyAd() only if the AdType is AdType.BANNER or Native Assembly Ad Type
if (!isLastResponseSuccessful()) {
Clog.w(Clog.lazyLoadLogTag, getContext().getString(R.string.apn_enable_lazy_webview_failure_non_banner));
return false;
}
Expand Down Expand Up @@ -1630,7 +1639,7 @@ protected void deactivateWebviewForNextCall() {
* see {@link ANAdResponseInfo}
*/
protected boolean isLastResponseSuccessful() {
return getAdResponseInfo() != null && getAdResponseInfo().getAdType() == AdType.BANNER;
return getAdResponseInfo() != null && (getAdResponseInfo().getAdType() == AdType.BANNER || (getAdResponseInfo().getAdType() == AdType.NATIVE && isEligibleForNativeAssemblyRendering()));
}

@Override
Expand All @@ -1650,4 +1659,12 @@ public Long getStartTime() {
public Long getFinishTime() {
return finishTime;
}

/**
* Retrieve the NativeAssemblyRenderer of the request
*
* @return true if it is NativeAssemblyRenderer, else false
* */
public boolean isEligibleForNativeAssemblyRendering() { return eligibleForNativeAssemblyRendering; }

}
16 changes: 12 additions & 4 deletions sdk/src/com/appnexus/opensdk/AdViewRequestManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,16 @@ private void handleNativeResponse(final Ad owner, final BaseAdResponse baseAdRes
}

if (owner instanceof BannerAdView && ((BannerAdView) owner).isNativeRenderingEnabled() && nativeAdResponse.getRendererUrl().length() > 0) {
initiateWebview(owner, baseAdResponse);
((AdView)owner).eligibleForNativeAssemblyRendering = true;
if (((BannerAdView)owner).isLazyWebviewInactive()) {
((AdDispatcher)owner.getAdDispatcher()).onLazyAdLoaded(currentAd.getAdResponseInfo());
} else {
initiateWebview(owner, baseAdResponse);
}
} else {
if (owner != null && owner instanceof BannerAdView) {
((AdView)owner).eligibleForNativeAssemblyRendering = false;
}
processNativeAd(nativeAdResponse, baseAdResponse);
}
}
Expand Down Expand Up @@ -344,8 +352,8 @@ private void handleRTBResponse(Ad ownerAd, BaseAdResponse rtbAdResponse) {
AdView owner = (AdView) ownerAd;
fireImpressionTrackerIfBeginToRender(owner, rtbAdResponse);
} else {
Clog.e(Clog.baseLogTag, "AdType can not be identified.");
continueWaterfall(ResultCode.getNewInstance(ResultCode.INVALID_REQUEST));
Clog.e(Clog.baseLogTag, "AdType cannot be identified.");
continueWaterfall(ResultCode.getNewInstance(ResultCode.INVALID_REQUEST, "AdType cannot be identified."));
}
}
} else {
Expand Down Expand Up @@ -408,7 +416,7 @@ private void handleCSMResponse(Ad ownerAd, final CSMSDKAdResponse csmSdkAdRespon
owner.getAdDispatcher());
} else {
Clog.e(Clog.baseLogTag, "MediaType type can not be identified.");
continueWaterfall(ResultCode.getNewInstance(ResultCode.INVALID_REQUEST));
continueWaterfall(ResultCode.getNewInstance(ResultCode.INVALID_REQUEST, "MediaType type can not be identified"));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public class CSRNativeBannerController implements CSRController {
this,
requester.getRequestParams().getTargetingParameters());
} else {
errorCode = ResultCode.getNewInstance(ResultCode.INVALID_REQUEST);
errorCode = ResultCode.getNewInstance(ResultCode.INVALID_REQUEST, "Unable to get CSR mediated request params");
}
} catch (ClassNotFoundException e) {
// exception in Class.forName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ private MediatedNativeAdController(CSMSDKAdResponse currentAd, UTAdRequester req
currentAd.getId(), this,
requester.getRequestParams().getTargetingParameters());
} else {
errorCode = ResultCode.getNewInstance(ResultCode.INVALID_REQUEST);
errorCode = ResultCode.getNewInstance(ResultCode.INVALID_REQUEST, "Mediated request params not found");
}
} catch (ClassNotFoundException e) {
// exception in Class.forName
Expand Down
6 changes: 3 additions & 3 deletions sdk/src/com/appnexus/opensdk/ut/UTAdRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ void processResponse(HashMap<String, UTAdResponse> adResponseMap) {

if (adResponseMap == null) {
Clog.e(Clog.httpRespLogTag, Clog.getString(R.string.no_response));
fail(ResultCode.getNewInstance(ResultCode.INVALID_REQUEST));
fail(ResultCode.getNewInstance(ResultCode.INVALID_REQUEST, "Server did not respond and failed to map response"));
return;
}

Expand All @@ -306,7 +306,7 @@ void processResponse(HashMap<String, UTAdResponse> adResponseMap) {
}
} else if (anMultiAdRequest != null) {
if (adResponseMap == null) {
ResultCode code = ResultCode.getNewInstance(ResultCode.INVALID_REQUEST);
ResultCode code = ResultCode.getNewInstance(ResultCode.INVALID_REQUEST, "Failed to map response");
Clog.e(Clog.SRMLogTag, "FAILED: " + code.getMessage());
anMultiAdRequest.onRequestFailed(code);
} else {
Expand All @@ -324,7 +324,7 @@ void processResponse(HashMap<String, UTAdResponse> adResponseMap) {
UTAdRequester requester = new AdViewRequestManager(ad);
ad.getMultiAd().setRequestManager(requester);
if (adResponseMap == null) {
ResultCode code = ResultCode.getNewInstance(ResultCode.INVALID_REQUEST);
ResultCode code = ResultCode.getNewInstance(ResultCode.INVALID_REQUEST, "Ad response mapping is null");
Clog.e(Clog.SRMLogTag, "FAILED: " + code.getMessage());
requester.failed(code, null);
continue;
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/com/appnexus/opensdk/utils/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public enum ImpressionType {
public boolean debug_mode = false; // This should always be false here.
public String ua = null;

public final String sdkVersion = "8.7";
public final String sdkVersion = "8.8";
// BuildConfig.VERSION_NAME;


Expand Down
102 changes: 102 additions & 0 deletions sdk/test/com/appnexus/opensdk/AdListenerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,109 @@ public void testloadLazyAdForDisabledLazyLoad() {
assertFalse(adFailed);
}

//Native Assembly Load Lazy Testing
@Test
public void testLazyNativeAssemblyAdLoaded() {
ShadowCustomWebView.simulateRendererScriptSuccess = true;
server.setDispatcher(getDispatcher(TestResponsesUT.anNativeRenderer()));
bannerAdView.setAllowNativeDemand(true);
bannerAdView.enableNativeRendering(true);
bannerAdView.enableLazyLoad();
executeBannerRequest();

assertLazyLoadCallbackInProgress();
bannerAdView.loadLazyAd();
Robolectric.flushBackgroundThreadScheduler();
Robolectric.flushForegroundThreadScheduler();
assertLazyLoadCallbackSuccess();
}

// This proves that the second loadAd() behaves as a Lazy load even after the Lazy Ad has already been loaded once (after calling loadLazyAd())
@Test
public void testLazyNativeAssemblyAdLoadedSuccessAndLoadAgain() {
ShadowCustomWebView.simulateRendererScriptSuccess = true;
server.setDispatcher(getDispatcher(TestResponsesUT.anNativeRenderer()));
bannerAdView.setAllowNativeDemand(true);
bannerAdView.enableNativeRendering(true);
bannerAdView.enableLazyLoad();
executeBannerRequest();
assertFalse(bannerAdView.getChildAt(0) instanceof WebView);
assertLazyLoadCallbackInProgress();
bannerAdView.loadLazyAd();
Robolectric.flushBackgroundThreadScheduler();
Robolectric.flushForegroundThreadScheduler();
assertLazyLoadCallbackSuccess();
assertTrue(bannerAdView.getChildAt(0) instanceof WebView);
adLoaded = false;
adLazyLoaded = false;
adFailed = false;
restartServer();
ShadowCustomWebView.simulateRendererScriptSuccess = true;
server.setDispatcher(getDispatcher(TestResponsesUT.anNativeRenderer()));
bannerAdView.setAllowNativeDemand(true);
bannerAdView.enableNativeRendering(true);
executeBannerRequest();
assertLazyLoadCallbackInProgress();
bannerAdView.loadLazyAd();
Robolectric.flushBackgroundThreadScheduler();
Robolectric.flushForegroundThreadScheduler();
assertLazyLoadCallbackSuccess();
assertTrue(bannerAdView.getChildAt(0) instanceof WebView);
Robolectric.flushBackgroundThreadScheduler();
Robolectric.flushForegroundThreadScheduler();
}

@Test
public void testloadLazyNativeAssemblyAdAfterAdLoad() {
ShadowCustomWebView.simulateRendererScriptSuccess = true;
server.setDispatcher(getDispatcher(TestResponsesUT.anNativeRenderer()));
bannerAdView.setAllowNativeDemand(true);
bannerAdView.enableNativeRendering(true);
assertTrue(bannerAdView.enableLazyLoad());
executeBannerRequest();
assertLazyLoadCallbackInProgress();
assertTrue(bannerAdView.loadLazyAd());
Robolectric.flushBackgroundThreadScheduler();
Robolectric.flushForegroundThreadScheduler();
assertLazyLoadCallbackSuccess();
adLoaded = false;
adFailed = false;
assertFalse(bannerAdView.loadLazyAd());
assertFalse(adLoaded);
assertFalse(adFailed);
}

@Test
public void testLazyNativeAssemblyAdLoadWithloadLazyAdAlreadyCalled() {
ShadowCustomWebView.simulateRendererScriptSuccess = true;
server.setDispatcher(getDispatcher(TestResponsesUT.anNativeRenderer()));
bannerAdView.setAllowNativeDemand(true);
bannerAdView.enableNativeRendering(true);
bannerAdView.enableLazyLoad();
assertFalse(bannerAdView.loadLazyAd());
executeBannerRequest();
assertLazyLoadCallbackInProgress();
assertTrue(bannerAdView.loadLazyAd());
Robolectric.flushBackgroundThreadScheduler();
Robolectric.flushForegroundThreadScheduler();
assertLazyLoadCallbackSuccess();
}

@Test
public void testLazyNativeAssemblyAdFailed() {
ShadowCustomWebView.simulateRendererScriptSuccess = false;
server.setDispatcher(getDispatcher(TestResponsesUT.anNativeRenderer())); // First queue a banner Native response
bannerAdView.setAllowNativeDemand(false);
bannerAdView.enableNativeRendering(false);
bannerAdView.enableLazyLoad();
executeBannerRequest();
bannerAdView.loadLazyAd();
Robolectric.flushBackgroundThreadScheduler();
Robolectric.flushForegroundThreadScheduler();
assertFalse(bannerAdView.loadLazyAd());
assertFalse(adFailed);
assertFalse(adLazyLoaded);
}

@Test
public void testBannerAdFailed() {
Expand Down

0 comments on commit df71129

Please sign in to comment.