diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 47adccaa..b7904770 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,3 +1,14 @@ +## 8.2 + +### Improvement/Bug Fixes ++ MS-5172 Support for Global Privacy Platform (GPP) [https://docs.xandr.com/bundle/mobile-sdk/page/sdk-privacy-for-android.html] ++ MS-5132 Add a boolean to notify success / failure for XandrAd InitListener [Github #74][https://docs.xandr.com/bundle/mobile-sdk/page/android-sdk-initialization-v8-0.html] ++ MS-5024 Updated ProGuard settings [Github #65] ++ MS-5190 NullPointerException while using loadAdFromVAST for BannerAdView + +### Mediation partner updates ++ MS-5195 Upgraded Facebook Audience Network SDK from 6.5.0 to 6.12.0 + ## 8.1 ### Improvement/Bug Fixes diff --git a/csr/Facebook/build.gradle b/csr/Facebook/build.gradle index 8781bb60..f952878d 100755 --- a/csr/Facebook/build.gradle +++ b/csr/Facebook/build.gradle @@ -1,5 +1,5 @@ // Project Properties -version = "6.5.0" // supported Facebook version +version = "6.12.0" // supported Facebook version apply plugin: 'com.android.library' diff --git a/examples/java/SimpleBanner/app/src/main/AndroidManifest.xml b/examples/java/SimpleBanner/app/src/main/AndroidManifest.xml index d0257b81..fe7494af 100644 --- a/examples/java/SimpleBanner/app/src/main/AndroidManifest.xml +++ b/examples/java/SimpleBanner/app/src/main/AndroidManifest.xml @@ -30,7 +30,8 @@ + android:configChanges="orientation|screenLayout|screenSize|keyboardHidden" + android:exported="true"> diff --git a/examples/java/SimpleBanner/app/src/main/java/com/example/simplebanner/MainApplication.kt b/examples/java/SimpleBanner/app/src/main/java/com/example/simplebanner/MainApplication.kt deleted file mode 100644 index f9aedf65..00000000 --- a/examples/java/SimpleBanner/app/src/main/java/com/example/simplebanner/MainApplication.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.example.simplebanner - -import android.app.Application -import android.widget.Toast -import com.appnexus.opensdk.XandrAd - -class MainApplication: Application() { - override fun onCreate() { - super.onCreate() - XandrAd.init(10094, this, true) { - Toast.makeText(this, "Init Completed", Toast.LENGTH_SHORT).show() - } - } -} \ No newline at end of file diff --git a/examples/java/SimpleBanner/app/src/main/java/com/example/simplebanner/MyActivity.java b/examples/java/SimpleBanner/app/src/main/java/com/example/simplebanner/MyActivity.java index 8a2a00fc..51d9da05 100644 --- a/examples/java/SimpleBanner/app/src/main/java/com/example/simplebanner/MyActivity.java +++ b/examples/java/SimpleBanner/app/src/main/java/com/example/simplebanner/MyActivity.java @@ -21,14 +21,17 @@ import android.os.Handler; import android.util.Log; import android.widget.RelativeLayout; +import android.widget.Toast; import com.appnexus.opensdk.ANClickThroughAction; import com.appnexus.opensdk.AdListener; import com.appnexus.opensdk.AdView; import com.appnexus.opensdk.BannerAdView; +import com.appnexus.opensdk.InitListener; import com.appnexus.opensdk.NativeAdResponse; import com.appnexus.opensdk.ResultCode; import com.appnexus.opensdk.SDKSettings; +import com.appnexus.opensdk.XandrAd; import com.appnexus.opensdk.utils.Clog; public class MyActivity extends Activity { @@ -39,6 +42,12 @@ public class MyActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); + XandrAd.init(10094, this, true, new InitListener() { + @Override + public void onInitFinished(boolean success) { + Toast.makeText(MyActivity.this, "Init Completed with " + success, Toast.LENGTH_SHORT).show(); + } + }); bav = new BannerAdView(this); diff --git a/examples/java/SimpleSRM/app/src/main/java/com/example/simplesrm/MainApplication.java b/examples/java/SimpleSRM/app/src/main/java/com/example/simplesrm/MainApplication.java index 28daf544..fd631537 100644 --- a/examples/java/SimpleSRM/app/src/main/java/com/example/simplesrm/MainApplication.java +++ b/examples/java/SimpleSRM/app/src/main/java/com/example/simplesrm/MainApplication.java @@ -12,9 +12,10 @@ public void onCreate() { super.onCreate(); XandrAd.init(10094, this, true, new InitListener() { @Override - public void onInitFinished() { - Toast.makeText(getApplicationContext(), "Init Completed", Toast.LENGTH_SHORT).show(); + public void onInitFinished(boolean success) { + Toast.makeText(getApplicationContext(), "Init Completed with " + success, Toast.LENGTH_SHORT).show(); } }); + } } \ No newline at end of file diff --git a/examples/java/SimpleVideo/app/src/main/java/com/appnexus/example/simplevideo/MainActivity.java b/examples/java/SimpleVideo/app/src/main/java/com/appnexus/example/simplevideo/MainActivity.java index 87a58f35..05689f03 100644 --- a/examples/java/SimpleVideo/app/src/main/java/com/appnexus/example/simplevideo/MainActivity.java +++ b/examples/java/SimpleVideo/app/src/main/java/com/appnexus/example/simplevideo/MainActivity.java @@ -65,7 +65,7 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); SDKSettings.init(this, new InitListener() { @Override - public void onInitFinished() { + public void onInitFinished(boolean success) { infoText = (TextView) findViewById(R.id.infotTextView); playButon = (ImageButton) findViewById(R.id.play_button); videoPlayer = (VideoView) findViewById(R.id.video_player); diff --git a/examples/java/SimpleVideo/app/src/main/java/com/appnexus/example/simplevideo/MainApplication.java b/examples/java/SimpleVideo/app/src/main/java/com/appnexus/example/simplevideo/MainApplication.java index a56747c4..1039d03f 100644 --- a/examples/java/SimpleVideo/app/src/main/java/com/appnexus/example/simplevideo/MainApplication.java +++ b/examples/java/SimpleVideo/app/src/main/java/com/appnexus/example/simplevideo/MainApplication.java @@ -12,9 +12,10 @@ public void onCreate() { super.onCreate(); XandrAd.init(10094, this, true, new InitListener() { @Override - public void onInitFinished() { - Toast.makeText(getApplicationContext(), "Init Completed", Toast.LENGTH_SHORT).show(); + public void onInitFinished(boolean success) { + Toast.makeText(getApplicationContext(), "Init Completed with " + success, Toast.LENGTH_SHORT).show(); } }); + } } \ No newline at end of file diff --git a/examples/kotlin/LazyLoadDemo/app/src/main/java/com/xandr/lazyloaddemo/MainApplication.kt b/examples/kotlin/LazyLoadDemo/app/src/main/java/com/xandr/lazyloaddemo/MainApplication.kt index 48d1d600..0d362e36 100644 --- a/examples/kotlin/LazyLoadDemo/app/src/main/java/com/xandr/lazyloaddemo/MainApplication.kt +++ b/examples/kotlin/LazyLoadDemo/app/src/main/java/com/xandr/lazyloaddemo/MainApplication.kt @@ -8,7 +8,7 @@ class MainApplication: Application() { override fun onCreate() { super.onCreate() XandrAd.init(10094, this, true) { - Toast.makeText(this, "Init Completed", Toast.LENGTH_SHORT).show() + Toast.makeText(this, "Init Completed with $it", Toast.LENGTH_SHORT).show() } } } \ No newline at end of file diff --git a/examples/kotlin/SimpleDemo/app/src/main/java/appnexus/example/kotlinsample/MainApplication.kt b/examples/kotlin/SimpleDemo/app/src/main/java/appnexus/example/kotlinsample/MainApplication.kt index a0061ce4..69af20f8 100644 --- a/examples/kotlin/SimpleDemo/app/src/main/java/appnexus/example/kotlinsample/MainApplication.kt +++ b/examples/kotlin/SimpleDemo/app/src/main/java/appnexus/example/kotlinsample/MainApplication.kt @@ -8,7 +8,7 @@ class MainApplication: Application() { override fun onCreate() { super.onCreate() XandrAd.init(10094, this, true) { - Toast.makeText(this, "Init Completed", Toast.LENGTH_SHORT).show() + Toast.makeText(this, "Init Completed with $it", Toast.LENGTH_SHORT).show() } } } \ No newline at end of file diff --git a/instreamvideo/build.gradle b/instreamvideo/build.gradle index 180dcb20..bc1367ab 100644 --- a/instreamvideo/build.gradle +++ b/instreamvideo/build.gradle @@ -1,5 +1,5 @@ // Project Properties -version = "1.39" // Instream SDK version +version = "1.40" // Instream SDK version apply plugin: 'com.android.library' @@ -10,7 +10,7 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 32 - versionCode 38 // An integer value that represents the version of the code, relative to other versions. Increase for each release. + versionCode 39 // An integer value that represents the version of the code, relative to other versions. Increase for each release. versionName version consumerProguardFiles 'proguard-project.txt' } diff --git a/sdk/build.gradle b/sdk/build.gradle index 2aa4d5ff..5bc422eb 100644 --- a/sdk/build.gradle +++ b/sdk/build.gradle @@ -1,5 +1,5 @@ // Project properties -version = "8.1" +version = "8.2" group='com.appnexus.opensdk' // Android build @@ -9,7 +9,7 @@ android { compileSdkVersion 32 buildToolsVersion '32.0.0' defaultConfig { - versionCode 97 // An integer value that represents the version of the code, relative to other versions. Increase for each release. + versionCode 98 // 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 @@ -22,7 +22,7 @@ android { main.res.srcDir 'res' main.assets.srcDir 'assets' main.resources.srcDir 'src' - test.manifest.srcFile 'AndroidManifestTest.xml' +// test.manifest.srcFile 'AndroidManifestTest.xml' test.java.srcDir 'test' } diff --git a/sdk/proguard-project.txt b/sdk/proguard-project.txt index a4b23ff3..ac094d27 100644 --- a/sdk/proguard-project.txt +++ b/sdk/proguard-project.txt @@ -24,27 +24,11 @@ -keep public class * implements com.appnexus.opensdk.MediatedNativeAd {public *;} -keep public class * implements com.appnexus.opensdk.CSRAd {public *;} -# Uncomment for Google Play Services library -#-keep class * extends java.util.ListResourceBundle { -# protected Object[][] getContents(); -#} -# -#-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable { -# public static final *** NULL; +# Uncomment to support for Android Advertiser ID. +#-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient { +# com.google.android.gms.ads.identifier.AdvertisingIdClient$Info getAdvertisingIdInfo(android.content.Context); #} -# -#-keepnames @com.google.android.gms.common.annotation.KeepName class * -# -#-keepclassmembernames class * { -# @com.google.android.gms.common.annotation.KeepName *; +#-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient$Info { +# java.lang.String getId(); +# boolean isLimitAdTrackingEnabled(); #} -# -#-keepnames class * implements android.os.Parcelable { -# public ** CREATOR; -#} - -# Uncomment to support for Android Advertiser ID. -#-keep class com.google.android.gms.common.GooglePlayServicesUtil {*;} -#-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient {*;} - - diff --git a/sdk/src/com/appnexus/opensdk/ANGDPRSettings.java b/sdk/src/com/appnexus/opensdk/ANGDPRSettings.java index 581124ff..a97a242a 100644 --- a/sdk/src/com/appnexus/opensdk/ANGDPRSettings.java +++ b/sdk/src/com/appnexus/opensdk/ANGDPRSettings.java @@ -49,6 +49,10 @@ public class ANGDPRSettings { // Google ACM consent parameter private static final String IABTCF_ADDTL_CONSENT = "IABTCF_AddtlConsent"; + // GPP consent parameters + private static final String IABGPP_TCFEU2_SubjectToGDPR = "IABGPP_TCFEU2_gdprApplies"; + private static final String IABGPP_TCFEU2_PurposeConsents = "IABGPP_TCFEU2_PurposeConsents"; + /** * Set the consent string in the SDK * @@ -173,6 +177,8 @@ public static Boolean getConsentRequired(Context context) { subjectToGdprValue = pref.getString(ANGDPR_CONSENT_REQUIRED, ""); } else if (pref.contains(IAB_SUBJECT_TO_GDPR)) { subjectToGdprValue = pref.getString(IAB_SUBJECT_TO_GDPR, ""); + } else if (pref.contains(IABGPP_TCFEU2_SubjectToGDPR)) { + subjectToGdprValue = pref.getString(IABGPP_TCFEU2_SubjectToGDPR, ""); } } @@ -208,7 +214,9 @@ public static String getDeviceAccessConsent(Context context) { if (pref.contains(IABTCF_PurposeConsents)){ deviceConsent = pref.getString(IABTCF_PurposeConsents, null); }else if (pref.contains(ANGDPR_PurposeConsents)) { - deviceConsent = pref.getString(ANGDPR_PurposeConsents, null); + deviceConsent = pref.getString(ANGDPR_PurposeConsents, null); + } else if (pref.contains(IABGPP_TCFEU2_PurposeConsents)) { + deviceConsent = pref.getString(IABGPP_TCFEU2_PurposeConsents, null); } return !StringUtil.isEmpty(deviceConsent) ? deviceConsent.substring(0, 1) : null; @@ -231,6 +239,4 @@ public static Boolean canIAccessDeviceData(Context context) { return false; } - - } diff --git a/sdk/src/com/appnexus/opensdk/AdView.java b/sdk/src/com/appnexus/opensdk/AdView.java index 6c5a2910..79c48b5a 100644 --- a/sdk/src/com/appnexus/opensdk/AdView.java +++ b/sdk/src/com/appnexus/opensdk/AdView.java @@ -259,22 +259,26 @@ public boolean loadAd(String placementID) { return loadAd(); } - protected void loadAdFromHtml(String html, int width, int height) { + protected void loadAdFromHtml(String html, int width, int height, int buyerMemberId) { // load an ad directly from html loadedOffscreen = true; AdWebView output = new AdWebView(this, null); - RTBHTMLAdResponse response = new RTBHTMLAdResponse(width, height, getMediaType().toString(), null, getAdResponseInfo()); + ANAdResponseInfo adResponseInfo = new ANAdResponseInfo(); + adResponseInfo.setBuyMemberId(buyerMemberId); + RTBHTMLAdResponse response = new RTBHTMLAdResponse(width, height, getMediaType().toString(), null, adResponseInfo); response.setAdContent(html); output.loadAd(response); display(output); } - protected void loadAdFromVAST(String VASTXML, int width, int height) { + protected void loadAdFromVAST(String VASTXML, int width, int height, int buyerMemberId) { // load an ad directly from VASTXML loadedOffscreen = true; AdWebView output = new AdWebView(this, null); - RTBVASTAdResponse response = new RTBVASTAdResponse(width, height, AdType.VIDEO.toString(), null, null, getAdResponseInfo()); + ANAdResponseInfo adResponseInfo = new ANAdResponseInfo(); + adResponseInfo.setBuyMemberId(buyerMemberId); + RTBVASTAdResponse response = new RTBVASTAdResponse(width, height, AdType.VIDEO.toString(), null, null, adResponseInfo); response.setAdContent(VASTXML); response.setContentSource(UTConstants.RTB); response.addToExtras(UTConstants.EXTRAS_KEY_MRAID, true); diff --git a/sdk/src/com/appnexus/opensdk/InitListener.java b/sdk/src/com/appnexus/opensdk/InitListener.java index 289dc46a..292f78e9 100644 --- a/sdk/src/com/appnexus/opensdk/InitListener.java +++ b/sdk/src/com/appnexus/opensdk/InitListener.java @@ -17,5 +17,5 @@ package com.appnexus.opensdk; public interface InitListener { - void onInitFinished(); + void onInitFinished(boolean success); } diff --git a/sdk/src/com/appnexus/opensdk/SDKSettings.java b/sdk/src/com/appnexus/opensdk/SDKSettings.java index e9960fee..cd96a933 100644 --- a/sdk/src/com/appnexus/opensdk/SDKSettings.java +++ b/sdk/src/com/appnexus/opensdk/SDKSettings.java @@ -476,7 +476,7 @@ public void run() { if (!isAAIDFetched) { AdvertisingIDUtil.retrieveAndSetAAID(context, new InitListener() { @Override - public void onInitFinished() { + public void onInitFinished(boolean success) { isAAIDFetched = true; SDKSettings.onInitFinished(listener); } @@ -492,7 +492,7 @@ private static void onInitFinished(final InitListener listener) { TasksManager.getInstance().executeOnMainThread(new Runnable() { @Override public void run() { - listener.onInitFinished(); + listener.onInitFinished(true); } }); } diff --git a/sdk/src/com/appnexus/opensdk/XandrAd.java b/sdk/src/com/appnexus/opensdk/XandrAd.java index 07f8aff1..c8fe0643 100644 --- a/sdk/src/com/appnexus/opensdk/XandrAd.java +++ b/sdk/src/com/appnexus/opensdk/XandrAd.java @@ -24,7 +24,6 @@ import org.json.JSONArray; import org.json.JSONException; -import org.json.JSONObject; import java.util.ArrayList; import java.util.List; @@ -63,16 +62,22 @@ public static void init(int memberId, Context context, boolean preCacheContent, if (!isSdkInitialised) { SDKSettings.init(context, new InitListener() { @Override - public void onInitFinished() { + public void onInitFinished(boolean success) { isSdkInitialised = true; if (initListener != null && areMemberIdsCached) { - initListener.onInitFinished(); + initListener.onInitFinished(success); } } }); } XandrAd.memberId = memberId; if (!areMemberIdsCached) { + if (context != null && !SharedNetworkManager.getInstance(context).isConnected(context)) { + if (initListener != null) { + initListener.onInitFinished(false); + return; + } + } HTTPGet fetchJson = new HTTPGet() { @Override protected void onPostExecute(HTTPResponse response) { @@ -92,7 +97,7 @@ protected void onPostExecute(HTTPResponse response) { areMemberIdsCached = true; if (initListener != null && isSdkInitialised) { - initListener.onInitFinished(); + initListener.onInitFinished(true); } } diff --git a/sdk/src/com/appnexus/opensdk/ut/ANGPPSettings.java b/sdk/src/com/appnexus/opensdk/ut/ANGPPSettings.java new file mode 100644 index 00000000..cdb7913e --- /dev/null +++ b/sdk/src/com/appnexus/opensdk/ut/ANGPPSettings.java @@ -0,0 +1,66 @@ +/* + * Copyright 2018 APPNEXUS INC + * + * 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.appnexus.opensdk.ut; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +import com.appnexus.opensdk.utils.Clog; + +import org.json.JSONArray; + +/** + * GPP Settings class used for UT request formation. + */ +class ANGPPSettings { + + // GPP consent parameters + private static final String IABGPP_HDR_GppString = "IABGPP_HDR_GppString"; + private static final String IABGPP_GppSID = "IABGPP_GppSID"; + + /** + * @return SharedPreference value for IABGPP_HDR_GppString (if any) in the String format + * */ + public static String getIabGppString(Context context) { + SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context); + return pref.getString(IABGPP_HDR_GppString, null); + } + + /** + * @return SharedPreference value for IABGPP_GppSID (if any) in the String format + * */ + public static JSONArray getIabGppSIDArray(Context context) { + SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context); + String sIds = pref.getString(IABGPP_GppSID, null); + if (sIds != null && sIds.length() > 0) { + String[] sIdStringArray = sIds.split("_"); + if (sIdStringArray.length > 0) { + try { + JSONArray sIdIntArray = new JSONArray(); + for (String sId: sIdStringArray) { + sIdIntArray.put(Integer.valueOf(sId)); + } + return sIdIntArray; + } catch (NumberFormatException e) { + Clog.e(Clog.baseLogTag, "GPP SIDs should be comma separated integers"); + } + } + } + return null; + } +} diff --git a/sdk/src/com/appnexus/opensdk/ut/UTRequestParameters.java b/sdk/src/com/appnexus/opensdk/ut/UTRequestParameters.java index 5863842f..e85d3d1c 100644 --- a/sdk/src/com/appnexus/opensdk/ut/UTRequestParameters.java +++ b/sdk/src/com/appnexus/opensdk/ut/UTRequestParameters.java @@ -53,7 +53,6 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Locale; -import java.util.Map; import java.util.UUID; import com.appnexus.opensdk.viewability.ANOmidViewabilty; @@ -173,6 +172,11 @@ public class UTRequestParameters { private static final String US_PRIVACY = "us_privacy"; + // GPP + private static final String PRIVACY = "privacy"; + private static final String GPP_SID = "gpp_sid"; + private static final String GPP = "gpp"; + private static final int ALLOWED_TYPE_BANNER = 1; private static final int ALLOWED_TYPE_INTERSTITIAL = 3; @@ -565,6 +569,12 @@ String getPostData() { postData.put(GDPR_CONSENT, gdprConsent); } + // add GDPR Consent + JSONObject privacy = getPrivacyObject(); + if (privacy != null && privacy.length() > 0) { + postData.put(PRIVACY, privacy); + } + // add IAB Support Signal if (SDKSettings.getOMEnabled()) { @@ -590,6 +600,22 @@ String getPostData() { return postData.toString(); } + private JSONObject getPrivacyObject() { + JSONObject privacyObject = new JSONObject(); + try { + Context context = this.getContext(); + if (context != null) { + JSONArray gppSidArray = ANGPPSettings.getIabGppSIDArray(context); + if (gppSidArray != null) { + privacyObject.put(GPP, ANGPPSettings.getIabGppString(context)); + privacyObject.put(GPP_SID, gppSidArray); + } + } + } catch (JSONException e) { + } + return privacyObject; + } + private JSONObject getGeoOverride() { try { JSONObject geoOverride = new JSONObject(); diff --git a/sdk/src/com/appnexus/opensdk/utils/AdvertisingIDUtil.java b/sdk/src/com/appnexus/opensdk/utils/AdvertisingIDUtil.java index 90cf388a..be884faa 100644 --- a/sdk/src/com/appnexus/opensdk/utils/AdvertisingIDUtil.java +++ b/sdk/src/com/appnexus/opensdk/utils/AdvertisingIDUtil.java @@ -18,7 +18,6 @@ import android.content.Context; import android.os.AsyncTask; -import android.os.Build; import android.util.Pair; import com.appnexus.opensdk.InitListener; @@ -118,7 +117,7 @@ public void run() { @Override public void run() { if (listener != null) { - listener.onInitFinished(); + listener.onInitFinished(true); } } }); @@ -154,7 +153,7 @@ protected void onPostExecute(Pair pair) { super.onPostExecute(pair); SDKSettings.setAAID(pair.first, pair.second); if (listener != null) { - listener.onInitFinished(); + listener.onInitFinished(true); } } } diff --git a/sdk/test/com/appnexus/opensdk/UTAdRequestTest.java b/sdk/test/com/appnexus/opensdk/UTAdRequestTest.java index 135eba48..579a1108 100644 --- a/sdk/test/com/appnexus/opensdk/UTAdRequestTest.java +++ b/sdk/test/com/appnexus/opensdk/UTAdRequestTest.java @@ -1,5 +1,9 @@ package com.appnexus.opensdk; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.content.Context; +import android.text.TextUtils; import android.content.SharedPreferences; import android.preference.PreferenceManager; @@ -629,6 +633,28 @@ public void testGDPRSettings() throws Exception { assertFalse(Settings.getSettings().deviceAccessAllowed); // When consent required set to true and no purpose consent string deviceAccess is not allowed } + /** + * Test GPP in /ut request body + * + * @throws Exception + */ + @Test + public void testGPPSettings() throws Exception { + executionSteps(); + JSONObject postDataBeforeGPPValueSet = inspectPostData(); + assertFalse(postDataBeforeGPPValueSet.has("privacy")); + + setGPPString(activity, "gppString"); + setGPPSID(activity, "1_2_3"); + executionSteps(); + JSONObject postDataWithGPPValueSet = inspectPostData(); + assertEquals("gppString", postDataWithGPPValueSet.getJSONObject("privacy").getString("gpp")); + JSONArray testArr = postDataWithGPPValueSet.getJSONObject("privacy").getJSONArray("gpp_sid"); + for (int i = 0; i < testArr.length(); i++) { + assertEquals(i+1, testArr.get(i)); + } + } + /** @@ -1345,4 +1371,27 @@ public void continueWaterfall(ResultCode reason) { @Override public void nativeRenderingFailed() { } + + /** + * Set the consent string in the SDK + * + * @param gppString + */ + private void setGPPString(Context context, String gppString) { + if(!TextUtils.isEmpty(gppString) && context != null) { + PreferenceManager.getDefaultSharedPreferences(context).edit().putString("IABGPP_HDR_GppString", gppString).apply(); + } + } + + + /** + * Set the consentRequired value in the SDK + * + * @param gppSid underscore (_) separated sid string + */ + private void setGPPSID(Context context, String gppSid) { + if (context != null) { + PreferenceManager.getDefaultSharedPreferences(context).edit().putString("IABGPP_GppSID", gppSid).apply(); + } + } } diff --git a/sdk/test/com/appnexus/opensdk/XandrAdTest.java b/sdk/test/com/appnexus/opensdk/XandrAdTest.java new file mode 100644 index 00000000..549afe7a --- /dev/null +++ b/sdk/test/com/appnexus/opensdk/XandrAdTest.java @@ -0,0 +1,169 @@ +/* + * Copyright 2020 APPNEXUS INC + * + * 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.appnexus.opensdk; + +import static android.os.Looper.getMainLooper; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; +import static org.robolectric.Shadows.shadowOf; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.Build; +import android.os.Handler; +import android.webkit.WebView; + +import com.appnexus.opensdk.util.Lock; +import com.appnexus.opensdk.util.MockMainActivity; +import com.appnexus.opensdk.utils.Clog; +import com.appnexus.opensdk.utils.Settings; +import com.appnexus.opensdk.utils.StringUtil; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; +import org.robolectric.shadows.ShadowConnectivityManager; +import org.robolectric.shadows.ShadowNetworkInfo; +import org.robolectric.util.ReflectionHelpers; +import org.robolectric.util.Scheduler; + +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.TimeUnit; + +@Config(sdk = Build.VERSION_CODES.LOLLIPOP) +@RunWith(RobolectricTestRunner.class) +public class XandrAdTest { + + private MockMainActivity activity; + private Scheduler bgScheduler; + private Scheduler uiScheduler; + private int sdkVersion; + private boolean success; + + private ConnectivityManager connectivityManager; + private ShadowConnectivityManager shadowConnectivityManager; + + private InitListener initListener = new InitListener() { + @Override + public void onInitFinished(boolean success) { + XandrAdTest.this.success = success; + } + }; + + @Before + public void setup() { + XandrAd.reset(); + success = false; + sdkVersion = ReflectionHelpers.getStaticField(Build.VERSION.class, "SDK_INT"); + Robolectric.getBackgroundThreadScheduler().reset(); + Robolectric.getForegroundThreadScheduler().reset(); + activity = Robolectric.buildActivity(MockMainActivity.class).create().start().resume().visible().get(); + shadowOf(activity).grantPermissions("android.permission.INTERNET"); + connectivityManager = (ConnectivityManager) activity.getSystemService(Context.CONNECTIVITY_SERVICE); + // Not using Shadows.shadowOf(connectivityManager) because of Robolectric bug when using API23+ + // See: https://github.com/robolectric/robolectric/issues/1862 + shadowConnectivityManager = (ShadowConnectivityManager) Shadow.extract(connectivityManager); + bgScheduler = Robolectric.getBackgroundThreadScheduler(); + uiScheduler = Robolectric.getForegroundThreadScheduler(); + Robolectric.flushBackgroundThreadScheduler(); + Robolectric.flushForegroundThreadScheduler(); + bgScheduler.pause(); + uiScheduler.pause(); + } + + @After + public void tearDown() { + activity.finish(); + shadowOf(getMainLooper()).quitUnchecked(); + bgScheduler.reset(); + uiScheduler.reset(); + Settings.getSettings().ua = null; + ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT", sdkVersion); + Clog.e("SDK_VERSION", sdkVersion + ""); + } + + @Test + public void testXandrAdInit() { + XandrAd.init(10094, activity, false, initListener); + waitForTasks(); + Robolectric.getBackgroundThreadScheduler().advanceToLastPostedRunnable(); + Robolectric.getForegroundThreadScheduler().advanceToLastPostedRunnable(); + + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + assertTrue(success); + } + + @Test + public void testXandrAdInitOffline() { + success = true; // to make sure that onInitCompleted is triggered with false (success) + goOffline(); + XandrAd.init(10094, activity, false, initListener); + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + assertFalse(success); + } + + private void scheduleTimerToCheckForTasks() { + Timer timer = new Timer(); + final int[] counter = {330}; + timer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + counter[0]--; + if (uiScheduler.areAnyRunnable() || bgScheduler.areAnyRunnable() || counter[0] == 0) { + Lock.unpause(); + this.cancel(); + } + } + }, 0, 100); + } + + public void waitForTasks() { + scheduleTimerToCheckForTasks(); + Lock.pause(); + } + + private void goOffline() { + NetworkInfo activeInfo = connectivityManager.getActiveNetworkInfo(); + Assert.assertTrue(activeInfo != null && activeInfo.isConnected()); + + shadowConnectivityManager.setActiveNetworkInfo( + ShadowNetworkInfo.newInstance(NetworkInfo.DetailedState.DISCONNECTED, ConnectivityManager.TYPE_MOBILE, 0, true, false) + ); + NetworkInfo activeInfo2 = connectivityManager.getActiveNetworkInfo(); + Assert.assertTrue(activeInfo2 != null && !activeInfo2.isConnected()); + } +} diff --git a/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/banner/BannerNativeTest.kt b/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/banner/BannerNativeTest.kt index 035d16cc..63ee8824 100644 --- a/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/banner/BannerNativeTest.kt +++ b/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/banner/BannerNativeTest.kt @@ -18,9 +18,11 @@ package appnexus.com.appnexussdktestapp.placement.banner import android.content.Intent import android.content.res.Resources +import androidx.test.espresso.Espresso import androidx.test.espresso.Espresso.onView import androidx.test.espresso.IdlingPolicies import androidx.test.espresso.IdlingRegistry +import androidx.test.espresso.assertion.ViewAssertions import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.isDisplayed @@ -31,10 +33,7 @@ import appnexus.com.appnexussdktestapp.BannerActivity import appnexus.com.appnexussdktestapp.R import com.appnexus.opensdk.XandrAd import com.microsoft.appcenter.espresso.Factory -import org.junit.After -import org.junit.Before -import org.junit.Rule -import org.junit.Test +import org.junit.* import org.junit.runner.RunWith import java.util.concurrent.TimeUnit @@ -76,6 +75,33 @@ class BannerNativeTest { reportHelper.label("Stopping App") } + /* + * Sanity Test for the Banner Ad of size 320x50 + * */ + @Test + fun bannerNativeLoadPerformanceTest() { + + bannerActivity.triggerAdLoad("17058950", allowNativeDemand = true) + + Espresso.onView(ViewMatchers.withId(R.id.linearLayout)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + Assert.assertTrue( + "Load time performance failure ${bannerActivity.getTime()}", + bannerActivity.getTime() < 2000 + ) + + Thread.sleep(500) + + bannerActivity.triggerAdLoad("17058950", allowNativeDemand = true) + + Espresso.onView(ViewMatchers.withId(R.id.linearLayout)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + Assert.assertTrue( + "Load time performance failure ${bannerActivity.getTime()}", + bannerActivity.getTime() < 2000 + ) + } + /* * Sanity Test for the Banner Native Ad * */ diff --git a/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/banner/BannerTest.kt b/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/banner/BannerTest.kt index 1bd01de2..b95101b1 100644 --- a/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/banner/BannerTest.kt +++ b/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/banner/BannerTest.kt @@ -72,6 +72,33 @@ class BannerTest { reportHelper.label("Stopping App") } + /* + * Sanity Test for the Banner Ad of size 320x50 + * */ + @Test + fun bannerLoadPerformanceTest() { + + bannerActivity.triggerAdLoad("17058950", 320, 50) + + Espresso.onView(ViewMatchers.withId(R.id.linearLayout)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + Assert.assertTrue( + "Load time performance failure ${bannerActivity.getTime()}", + bannerActivity.getTime() > 2000 + ) + + Thread.sleep(500) + + bannerActivity.triggerAdLoad("17058950", 320, 50) + + Espresso.onView(ViewMatchers.withId(R.id.linearLayout)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + Assert.assertTrue( + "Load time performance failure ${bannerActivity.getTime()}", + bannerActivity.getTime() < 2000 + ) + } + /* * Sanity Test for the Banner Ad of size 320x50 * */ @@ -126,7 +153,6 @@ class BannerTest { bannerActivity.banner.getChildAt(0).height.dp >= (bannerActivity.banner.adHeight - 1) || bannerActivity.banner.getChildAt(0).height.dp <= (bannerActivity.banner.adHeight + 1) ) - } diff --git a/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/banner/BannerVideoTest.kt b/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/banner/BannerVideoTest.kt index 9dd6220a..f8a7b9e2 100644 --- a/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/banner/BannerVideoTest.kt +++ b/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/banner/BannerVideoTest.kt @@ -74,6 +74,33 @@ class BannerVideoTest { reportHelper.label("Stopping App") } + /* + * Sanity Test for the Banner Ad of size 320x50 + * */ + @Test + fun bannerVideoLoadPerformanceTest() { + + bannerActivity.triggerAdLoad("17058950", allowVideoDemand = true) + + Espresso.onView(ViewMatchers.withId(R.id.linearLayout)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + Assert.assertTrue( + "Load time performance failure ${bannerActivity.getTime()}", + bannerActivity.getTime() > 2000 + ) + + Thread.sleep(500) + + bannerActivity.triggerAdLoad("17058950", allowVideoDemand = true) + + Espresso.onView(ViewMatchers.withId(R.id.linearLayout)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + Assert.assertTrue( + "Load time performance failure ${bannerActivity.getTime()}", + bannerActivity.getTime() < 2000 + ) + } + /* * Sanity Test for the Banner Video (Outstream Video) * */ diff --git a/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/interstitial/InterstitialTest.kt b/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/interstitial/InterstitialTest.kt index b766edf1..6888ecd5 100644 --- a/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/interstitial/InterstitialTest.kt +++ b/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/interstitial/InterstitialTest.kt @@ -24,6 +24,7 @@ import androidx.test.espresso.IdlingRegistry import androidx.test.espresso.action.ViewActions import androidx.test.espresso.assertion.ViewAssertions import androidx.test.espresso.intent.Intents.intended +import androidx.test.espresso.intent.Intents.times import androidx.test.espresso.intent.matcher.IntentMatchers import androidx.test.espresso.intent.rule.IntentsTestRule import androidx.test.espresso.matcher.ViewMatchers @@ -33,11 +34,8 @@ import appnexus.com.appnexussdktestapp.InterstitialActivity import com.appnexus.opensdk.AdActivity import com.appnexus.opensdk.XandrAd import com.microsoft.appcenter.espresso.Factory -import org.junit.After +import org.junit.* import org.junit.Assert.assertTrue -import org.junit.Before -import org.junit.Rule -import org.junit.Test import org.junit.runner.RunWith import java.util.concurrent.TimeUnit @@ -71,6 +69,37 @@ class InterstitialTest { reportHelper.label("Stopping App") } + /* + * Sanity Test for the Banner Ad of size 320x50 + * */ + @Test + fun interstitialLoadPerformanceTest() { + + interstitialActivity.triggerAdLoad("17058950", autoDismiss = -1, closeButtonDelay = 2) + + intended(IntentMatchers.hasComponent(AdActivity::class.java.name)) + + Assert.assertTrue( + "Load time performance failure ${interstitialActivity.getTime()}", + interstitialActivity.getTime() > 2000 + ) + + Thread.sleep(500) + + Espresso.pressBack() + + Thread.sleep(500) + + interstitialActivity.triggerAdLoad("17058950", autoDismiss = -1, closeButtonDelay = 2) + + intended(IntentMatchers.hasComponent(AdActivity::class.java.name), times(2)) + + Assert.assertTrue( + "Load time performance failure ${interstitialActivity.getTime()}", + interstitialActivity.getTime() < 3000 + ) + } + /* * Sanity Test for the Interstitial Ad along with autoDismissDelay of 5 sec * */ diff --git a/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/native/NativeTest.kt b/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/native/NativeTest.kt index 86d00de3..1c965f65 100644 --- a/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/native/NativeTest.kt +++ b/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/native/NativeTest.kt @@ -67,6 +67,33 @@ class NativeTest { reportHelper.label("Stopping App") } + /* + * Sanity Test for the Banner Ad of size 320x50 + * */ + @Test + fun nativeLoadPerformanceTest() { + + nativeActivity.triggerAdLoad("17058950") + + Espresso.onView(ViewMatchers.withId(R.id.title)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + Assert.assertTrue( + "Load time performance failure ${nativeActivity.getTime()}", + nativeActivity.getTime() < 2000 + ) + + Thread.sleep(500) + + nativeActivity.triggerAdLoad("17058950") + + Espresso.onView(ViewMatchers.withId(R.id.title)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + Assert.assertTrue( + "Load time performance failure ${nativeActivity.getTime()}", + nativeActivity.getTime() < 2000 + ) + } + /* * Sanity Test for the Native Ad * */ diff --git a/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/video/VideoTest.kt b/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/video/VideoTest.kt index 713a8112..cfe10818 100644 --- a/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/video/VideoTest.kt +++ b/tests/AppNexusSDKTestApp/app/src/androidTest/java/appnexus/com/appnexussdktestapp/placement/video/VideoTest.kt @@ -18,11 +18,14 @@ package appnexus.com.appnexussdktestapp.placement.video import android.content.Intent +import androidx.test.espresso.Espresso import androidx.test.espresso.Espresso.onView import androidx.test.espresso.IdlingPolicies import androidx.test.espresso.IdlingRegistry import androidx.test.espresso.action.ViewActions +import androidx.test.espresso.assertion.ViewAssertions import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.web.assertion.WebViewAssertions @@ -36,10 +39,7 @@ import appnexus.com.appnexussdktestapp.R import appnexus.com.appnexussdktestapp.VideoActivity import com.appnexus.opensdk.XandrAd import com.microsoft.appcenter.espresso.Factory -import org.junit.After -import org.junit.Before -import org.junit.Rule -import org.junit.Test +import org.junit.* import org.junit.runner.RunWith import java.util.concurrent.TimeUnit @@ -73,6 +73,33 @@ class VideoTest { reportHelper.label("Stopping App") } + /* + * Sanity Test for the Banner Ad of size 320x50 + * */ + @Test + fun videoLoadPerformanceTest() { + + videoActivity.triggerAdLoad("17058950") + + Espresso.onView(ViewMatchers.withId(R.id.linearLayout)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + Assert.assertTrue( + "Load time performance failure ${videoActivity.getTime()}", + videoActivity.getTime() <= 2000 + ) + + Thread.sleep(500) + + videoActivity.triggerAdLoad("17058950") + + Espresso.onView(ViewMatchers.withId(R.id.linearLayout)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + Assert.assertTrue( + "Load time performance failure ${videoActivity.getTime()}", + videoActivity.getTime() < 2000 + ) + } + /* * Sanity Test for the Video Ad (Instream Video) * */ diff --git a/tests/AppNexusSDKTestApp/app/src/main/java/appnexus/com/appnexussdktestapp/BannerActivity.kt b/tests/AppNexusSDKTestApp/app/src/main/java/appnexus/com/appnexussdktestapp/BannerActivity.kt index 7196d19a..f9227292 100644 --- a/tests/AppNexusSDKTestApp/app/src/main/java/appnexus/com/appnexussdktestapp/BannerActivity.kt +++ b/tests/AppNexusSDKTestApp/app/src/main/java/appnexus/com/appnexussdktestapp/BannerActivity.kt @@ -4,6 +4,7 @@ import android.os.Build import android.os.Bundle import android.os.Handler import android.os.Looper +import android.util.Log import android.view.View import android.view.View.GONE import android.view.View.VISIBLE @@ -22,6 +23,8 @@ import com.squareup.picasso.Picasso class BannerActivity : AppCompatActivity(), AdListener { + private var startTime: Long = 0L + private var finalTime: Long = 0L private lateinit var nativeView: View var impressionLogged = false var shouldDisplay: Boolean = true @@ -50,6 +53,7 @@ class BannerActivity : AppCompatActivity(), AdListener { } override fun onAdRequestFailed(p0: AdView?, p1: ResultCode?) { + finalTime = System.currentTimeMillis() Toast.makeText(this, "Ad Failed: " + p1?.message, Toast.LENGTH_LONG).show() println(p1?.message) if (!idlingResource.isIdleNow) @@ -65,6 +69,7 @@ class BannerActivity : AppCompatActivity(), AdListener { } override fun onAdLoaded(ad: AdView?) { + finalTime = System.currentTimeMillis() Toast.makeText(this, "AdLoaded", Toast.LENGTH_LONG).show() if (layout.childCount > 0) layout.removeAllViews() @@ -77,6 +82,7 @@ class BannerActivity : AppCompatActivity(), AdListener { } override fun onAdLoaded(nativeAdResponse: NativeAdResponse?) { + finalTime = System.currentTimeMillis() Toast.makeText(this, "Native Ad Loaded", Toast.LENGTH_LONG).show() handleNativeResponse(nativeAdResponse) } @@ -130,6 +136,7 @@ class BannerActivity : AppCompatActivity(), AdListener { val utils = Utils() utils.setForceCreativeId(creativeId, banner = banner); } + startTime = System.currentTimeMillis() banner.loadAd() } } @@ -202,4 +209,10 @@ class BannerActivity : AppCompatActivity(), AdListener { } }) } + + fun getTime(): Long { + val totalTime = finalTime - startTime + Log.e("TOTAL TIME", "$totalTime") + return totalTime + } } diff --git a/tests/AppNexusSDKTestApp/app/src/main/java/appnexus/com/appnexussdktestapp/InterstitialActivity.kt b/tests/AppNexusSDKTestApp/app/src/main/java/appnexus/com/appnexussdktestapp/InterstitialActivity.kt index 1b3a4d9a..c8ea62a5 100644 --- a/tests/AppNexusSDKTestApp/app/src/main/java/appnexus/com/appnexussdktestapp/InterstitialActivity.kt +++ b/tests/AppNexusSDKTestApp/app/src/main/java/appnexus/com/appnexussdktestapp/InterstitialActivity.kt @@ -3,6 +3,7 @@ package appnexus.com.appnexussdktestapp import android.os.Bundle import android.os.Handler import android.os.Looper +import android.util.Log import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.test.espresso.idling.CountingIdlingResource @@ -12,6 +13,8 @@ import com.appnexus.opensdk.utils.Settings class InterstitialActivity : AppCompatActivity(), AdListener { + private var startTime: Long = 0L + private var finalTime: Long = 0L var isAdCollapsed: Boolean = false var isAdExpanded: Boolean = false var idlingResource: CountingIdlingResource = CountingIdlingResource("Interstitial Load Counter", true) @@ -40,6 +43,7 @@ class InterstitialActivity : AppCompatActivity(), AdListener { } override fun onAdRequestFailed(p0: AdView?, p1: ResultCode?) { + finalTime = System.currentTimeMillis() Toast.makeText(this, "Ad Failed: " + p1?.message, Toast.LENGTH_LONG).show() println(p1?.message) if (!idlingResource.isIdleNow) @@ -54,6 +58,7 @@ class InterstitialActivity : AppCompatActivity(), AdListener { } override fun onAdLoaded(ad: AdView?) { + finalTime = System.currentTimeMillis() Toast.makeText(this, "AdLoaded", Toast.LENGTH_LONG).show() if (!idlingResource.isIdleNow) idlingResource.decrement() @@ -66,6 +71,7 @@ class InterstitialActivity : AppCompatActivity(), AdListener { } override fun onAdLoaded(p0: NativeAdResponse?) { + finalTime = System.currentTimeMillis() Toast.makeText(this, "Native Ad Loaded", Toast.LENGTH_LONG).show() if (!idlingResource.isIdleNow) idlingResource.decrement() @@ -98,6 +104,7 @@ class InterstitialActivity : AppCompatActivity(), AdListener { val utils = Utils() utils.setForceCreativeId(creativeId, interstitial = interstitial); } + startTime = System.currentTimeMillis() interstitial.loadAd() idlingResource.increment() @@ -110,4 +117,10 @@ class InterstitialActivity : AppCompatActivity(), AdListener { } super.onDestroy() } + + fun getTime(): Long { + val totalTime = finalTime - startTime + Log.e("TOTAL TIME", "$totalTime") + return totalTime + } } diff --git a/tests/AppNexusSDKTestApp/app/src/main/java/appnexus/com/appnexussdktestapp/NativeActivity.kt b/tests/AppNexusSDKTestApp/app/src/main/java/appnexus/com/appnexussdktestapp/NativeActivity.kt index 0b1bf1e1..45e2bb77 100644 --- a/tests/AppNexusSDKTestApp/app/src/main/java/appnexus/com/appnexussdktestapp/NativeActivity.kt +++ b/tests/AppNexusSDKTestApp/app/src/main/java/appnexus/com/appnexussdktestapp/NativeActivity.kt @@ -3,6 +3,7 @@ package appnexus.com.appnexussdktestapp import android.os.Bundle import android.os.Handler import android.os.Looper +import android.util.Log import android.view.View import android.widget.ImageView import android.widget.TextView @@ -18,12 +19,15 @@ import kotlinx.android.synthetic.main.layout_native.* class NativeActivity : AppCompatActivity(), NativeAdRequestListener, NativeAdEventListener { + private var startTime: Long = 0L + private var finalTime: Long = 0L var shouldDisplay: Boolean = true var didLogImpression: Boolean = false lateinit var nativeAdRequest: NativeAdRequest var idlingResource: CountingIdlingResource = CountingIdlingResource("Native Load Count", true) override fun onAdLoaded(nativeAdResponse: NativeAdResponse?) { + finalTime = System.currentTimeMillis() Toast.makeText(this, "Native Ad Loaded", Toast.LENGTH_LONG).show() TasksManager.getInstance().executeOnMainThread { handleNativeResponse(nativeAdResponse) @@ -31,6 +35,7 @@ class NativeActivity : AppCompatActivity(), NativeAdRequestListener, NativeAdEve } override fun onAdFailed(errorcode: ResultCode?, adResponseinfo: ANAdResponseInfo?) { + finalTime = System.currentTimeMillis() if (!idlingResource.isIdleNow) idlingResource.decrement() } @@ -70,7 +75,7 @@ class NativeActivity : AppCompatActivity(), NativeAdRequestListener, NativeAdEve utils.setForceCreativeId(creativeId, nativeAdRequest = nativeAdRequest); } - + startTime = System.currentTimeMillis() if (useExecutor) { TasksManager.getInstance().executeOnBackgroundThread({ nativeAdRequest.loadAd() @@ -119,4 +124,10 @@ class NativeActivity : AppCompatActivity(), NativeAdRequestListener, NativeAdEve override fun onAdWillLeaveApplication() { } + + fun getTime(): Long { + val totalTime = finalTime - startTime + Log.e("TOTAL TIME", "$totalTime") + return totalTime + } } diff --git a/tests/AppNexusSDKTestApp/app/src/main/java/appnexus/com/appnexussdktestapp/VideoActivity.kt b/tests/AppNexusSDKTestApp/app/src/main/java/appnexus/com/appnexussdktestapp/VideoActivity.kt index 0f8439fa..39f22849 100644 --- a/tests/AppNexusSDKTestApp/app/src/main/java/appnexus/com/appnexussdktestapp/VideoActivity.kt +++ b/tests/AppNexusSDKTestApp/app/src/main/java/appnexus/com/appnexussdktestapp/VideoActivity.kt @@ -8,6 +8,7 @@ import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.os.Handler import android.os.Looper +import android.util.Log import android.view.View import android.webkit.WebView import android.widget.* @@ -23,12 +24,15 @@ import com.appnexus.opensdk.utils.Settings class VideoActivity : AppCompatActivity(), VideoAdLoadListener { + private var startTime: Long = 0L + private var finalTime: Long = 0L private lateinit var baseContainer: RelativeLayout private lateinit var playButon: ImageButton private lateinit var videoPlayer: VideoView private lateinit var context: Context override fun onAdLoaded(videoAd: VideoAd?) { + finalTime = System.currentTimeMillis() Toast.makeText( this, "Ad is ready. Hit on Play button to start", Toast.LENGTH_SHORT @@ -38,6 +42,7 @@ class VideoActivity : AppCompatActivity(), VideoAdLoadListener { } override fun onAdRequestFailed(videoAd: VideoAd?, errorCode: ResultCode?) { + finalTime = System.currentTimeMillis() Toast.makeText(this, "Ad Failed: " + errorCode?.message, Toast.LENGTH_LONG).show() println(errorCode?.message) idlingResource.decrement() @@ -141,6 +146,7 @@ class VideoActivity : AppCompatActivity(), VideoAdLoadListener { } }) + startTime = System.currentTimeMillis() video.loadAd() idlingResource.increment() } @@ -152,4 +158,11 @@ class VideoActivity : AppCompatActivity(), VideoAdLoadListener { } super.onDestroy() } + + fun getTime(): Long { + val totalTime = finalTime - startTime + Log.e("TOTAL TIME", "$totalTime") + return totalTime + } + }