Skip to content

Commit

Permalink
feat: saving application context even if activity context was placed #…
Browse files Browse the repository at this point in the history
…447

Add request to status endpoint when init SDK. Check if previous init context is null when call init SDK. Replace all setApplicationContext SDK calls with new ones.
  • Loading branch information
ValentinPostindustria committed May 18, 2022
1 parent ba3e140 commit fc0f441
Show file tree
Hide file tree
Showing 17 changed files with 177 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import android.app.Application;
import android.os.Build;
import android.webkit.WebView;
import org.prebid.mobile.Host;
import org.prebid.mobile.PrebidMobile;
import org.prebid.mobile.javademo.utils.ScreenUtils;

Expand All @@ -29,7 +30,12 @@ public void onCreate() {
super.onCreate();

PrebidMobile.setShareGeoLocation(true);
PrebidMobile.setApplicationContext(getApplicationContext());

PrebidMobile.setPrebidServerAccountId("0689a263-318d-448b-a3d4-b02e8a709d9d");
PrebidMobile.setPrebidServerHost(
Host.createCustomHost("https://prebid-server-test-j.prebid.org/openrtb2/auction")
);
PrebidMobile.initializeSdk(getApplicationContext(), null);

ScreenUtils.closeSystemWindowsAndKeepScreenOn(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ class CustomApplication : Application() {


private fun initPrebidSDK() {
// PrebidMobile.setPbsDebug(true)
PrebidMobile.setApplicationContext(applicationContext)
AdTypesRepository.usePrebidServer()
PrebidMobile.initializeSdk(applicationContext, null)
PrebidMobile.setShareGeoLocation(true)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,9 @@ abstract class AdFragment : BaseFragment() {
val hostUrl = PrebidMobile.getPrebidServerHost().hostUrl
val host = Host.CUSTOM
host.hostUrl = hostUrl
PrebidMobile.setApplicationContext(requireContext())
PrebidMobile.setPrebidServerHost(host)
PrebidMobile.setPrebidServerAccountId(PrebidMobile.getPrebidServerAccountId())
PrebidMobile.initializeSdk(requireContext(), null)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import androidx.multidex.MultiDex
import androidx.multidex.MultiDexApplication
import com.applovin.sdk.AppLovinSdk
import com.applovin.sdk.AppLovinSdkConfiguration
import org.prebid.mobile.Host
import org.prebid.mobile.PrebidMobile
import org.prebid.mobile.renderingtestapp.utils.DemoItemProvider
import org.prebid.mobile.renderingtestapp.utils.SourcePicker
Expand All @@ -42,7 +43,8 @@ class InternalTestApplication : MultiDexApplication() {
super.onCreate()
instance = this

PrebidMobile.setApplicationContext(this)
PrebidMobile.setPrebidServerHost(Host.createCustomHost("https://prebid-server-test-j.prebid.org/openrtb2/auction"))
PrebidMobile.initializeSdk(this, null)
PrebidMobile.setPrebidServerAccountId(getString(R.string.prebid_account_id_prod))
PrebidMobile.logLevel = PrebidMobile.LogLevel.DEBUG
SourcePicker.setBidServerHost(SourcePicker.PBS_SERVER_DOMAIN)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,15 @@ public static HashMap<String, String> getCustomHeaders() {
return PrebidMobile.customHeaders;
}


/**
* Initializes the main SDK classes. Makes request to Prebid server to check its status.
* You have to set host url ({@link PrebidMobile#setPrebidServerHost(Host)}) before calling this method.
*
* @param context any context (must be not null)
* @param listener initialization listener (can be null)
* @see <a href="https://docs.prebid.org/prebid-server/endpoints/pbs-endpoint-status.html">GET /status</a>
*/
public static void initializeSdk(
@Nullable Context context,
@Nullable SdkInitializationListener listener
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,7 @@ protected void initBidLoader() {
}

private void initSdk(Context context) {
PrebidMobile.setApplicationContext(context, () -> {
});
PrebidMobile.initializeSdk(context, null);
}

private void cancelRefresh() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ private void init() {
}

private void initPrebidRenderingSdk() {
PrebidMobile.setApplicationContext(getContext());
PrebidMobile.initializeSdk(getContext(), null);
}

private void initBidLoader() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ protected void changeInterstitialAdUnitState(InterstitialAdUnitState state) {
}

private void initPrebidRenderingSdk() {
PrebidMobile.setApplicationContext(getContext(), () -> {});
PrebidMobile.initializeSdk(getContext(), null);
}

private void initBidLoader() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.prebid.mobile.rendering.sdk;

import android.app.Activity;
import android.content.Context;
import androidx.annotation.Nullable;
import org.prebid.mobile.LogUtil;
Expand All @@ -17,7 +18,7 @@ public class SdkInitializer {
private static boolean isSdkInitialized = false;

private static final AtomicInteger INIT_SDK_TASK_COUNT = new AtomicInteger();
private static final int MANDATORY_TASK_COUNT = 3;
private static final int MANDATORY_TASK_COUNT = 4;

private static SdkInitializationListener sdkInitListener;

Expand All @@ -30,9 +31,18 @@ public static void init(
return;
}

if (isSdkInitialized) {
if (context instanceof Activity) {
Context applicationContext = context.getApplicationContext();
if (applicationContext != null) {
context = applicationContext;
}
}

if (isSdkInitialized && ManagersResolver.getInstance().getContext() != null) {
return;
}
isSdkInitialized = false;

LogUtil.debug(TAG, "Initializing Prebid Rendering SDK");

sdkInitListener = listener;
Expand All @@ -44,6 +54,7 @@ public static void init(
AppInfoManager.init(context);
initOpenMeasurementSDK(context);
ManagersResolver.getInstance().prepare(context);
StatusRequester.makeRequest(listener);
}

private static void initializeLogging() {
Expand All @@ -63,8 +74,7 @@ private static void initOpenMeasurementSDK(Context context) {
public static void increaseTaskCount() {
if (INIT_SDK_TASK_COUNT.incrementAndGet() >= MANDATORY_TASK_COUNT) {
isSdkInitialized = true;
LogUtil.debug(TAG, "Prebid Rendering SDK " + PrebidMobile.SDK_VERSION + " Initialized");

LogUtil.debug(TAG, "Prebid SDK " + PrebidMobile.SDK_VERSION + " initialized");
if (sdkInitListener != null) {
sdkInitListener.onSdkInit();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package org.prebid.mobile.rendering.sdk;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.json.JSONException;
import org.json.JSONObject;
import org.prebid.mobile.LogUtil;
import org.prebid.mobile.PrebidMobile;
import org.prebid.mobile.rendering.listeners.SdkInitializationListener;
import org.prebid.mobile.rendering.networking.BaseNetworkTask;
import org.prebid.mobile.rendering.networking.ResponseHandler;
import org.prebid.mobile.rendering.networking.tracking.ServerConnection;

public class StatusRequester {

private static final String TAG = StatusRequester.class.getSimpleName();

public static void makeRequest(@Nullable SdkInitializationListener listener) {
String url = PrebidMobile.getPrebidServerHost().getHostUrl();
if (url.contains("/openrtb2/auction")) {
String statusUrl = url.replace("/openrtb2/auction", "/status");
ServerConnection.fireWithResult(
statusUrl,
getResponseHandler(listener)
);
} else if (url.isEmpty()) {
onInitError("Please set host url (PrebidMobile.setPrebidServerHost) and only then run SDK initialization.", listener);
} else {
onInitError("Error, url doesn't contain /openrtb2/auction part", listener);
}
}

private static ResponseHandler getResponseHandler(@Nullable SdkInitializationListener listener) {
return new ResponseHandler() {
@Override
public void onResponse(BaseNetworkTask.GetUrlResult response) {
if (response.statusCode == 200) {
try {
JSONObject responseJson = new JSONObject(response.responseString);
JSONObject applicationJson = responseJson.optJSONObject("application");
if (applicationJson != null) {
String status = applicationJson.optString("status");
if (status.equalsIgnoreCase("ok")) {
onSuccess();
return;
}
}
} catch (JSONException exception) {
onInitError("JsonException: " + exception.getMessage(), listener);
return;
}
}
onInitError("Server status is not ok!", listener);
}

@Override
public void onError(
String msg,
long responseTime
) {
onInitError("Exception: " + msg, listener);
}

@Override
public void onErrorWithException(
Exception exception,
long responseTime
) {
onInitError("Exception: " + exception.getMessage(), listener);
}
};
}

private static void onSuccess() {
SdkInitializer.increaseTaskCount();
}

private static void onInitError(
@NonNull String message,
@Nullable SdkInitializationListener listener
) {
LogUtil.error(TAG, message);
if (listener != null) {
listener.onSdkFailedToInit(new SdkInitializationListener.InitError(message));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ protected void init() throws AdException {
int visibility = getVisibility();

setScreenVisibility(visibility);
PrebidMobile.setApplicationContext(getContext(), null);
PrebidMobile.initializeSdk(getContext(), null);
}

protected void registerEventBroadcast() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import okhttp3.HttpUrl;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -30,27 +33,40 @@
import org.prebid.mobile.test.utils.WhiteBox;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.LinkedHashMap;
import java.util.Map;

import static android.os.Looper.getMainLooper;
import static java.lang.Thread.sleep;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.*;
import static org.robolectric.Shadows.shadowOf;

@RunWith(RobolectricTestRunner.class)
@Config(sdk = 19)
public class PrebidMobileTest {

private MockWebServer server;

@Before
public void setUp() throws Exception {
server = new MockWebServer();

initAndroidVersion();
}

@After
public void tearDown() throws IOException {
server.shutdown();

PrebidMobile.setStoredAuctionResponse(null);
PrebidMobile.clearStoredBidResponses();
}

// Sets Build.VERSION.SDK_INT to LOLLIPOP(21) which prevents ProviderInstaller from execution
private void initAndroidVersion() throws NoSuchFieldException, IllegalAccessException {
Field versionField = (Build.VERSION.class.getField("SDK_INT"));
Expand All @@ -63,12 +79,6 @@ private void initAndroidVersion() throws NoSuchFieldException, IllegalAccessExce
versionField.set(null, Build.VERSION_CODES.LOLLIPOP);
}

@After
public void tearDown() throws Exception {
PrebidMobile.setStoredAuctionResponse(null);
PrebidMobile.clearStoredBidResponses();
}

@Test
public void testGetDeviceName() throws Exception {
assertEquals("Unknown robolectric", AppInfoManager.getDeviceName());
Expand All @@ -78,10 +88,26 @@ public void testGetDeviceName() throws Exception {
public void testOnSDKInitWithoutVideoPreCache() throws Exception {
//test if sdkinit is sent even if precache fails for any reason, as it is optional & should not avoid further sdk actions
WhiteBox.field(SdkInitializer.class, "isSdkInitialized").set(null, false);

MockResponse mockResponse = new MockResponse();
mockResponse.setResponseCode(200);
mockResponse.setBody("{\n \"application\": {\n \"status\": \"ok\"\n }\n}");
server.enqueue(mockResponse);
server.start();
HttpUrl url = server.url("/status");
server.setProtocolNegotiationEnabled(false);

PrebidMobile.setPrebidServerHost(Host.createCustomHost(
url.toString().replace("/status", "/openrtb2/auction")
));

Context context = Robolectric.buildActivity(Activity.class).create().get();
SdkInitListener mockSdkInitListener = mock(SdkInitListener.class);

PrebidMobile.setApplicationContext(context, mockSdkInitListener);

sleep(300);
shadowOf(getMainLooper()).idle();
sleep(200);
verify(mockSdkInitListener, times(1)).onSDKInit();
}

Expand Down Expand Up @@ -126,4 +152,5 @@ public void addAndClearStoredBidResponseMap_ReturnExpectedResult() {

assertTrue(PrebidMobile.getStoredBidResponses().isEmpty());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.applovin.mediation.adapters.prebid.managers.MaxNativeManager;
import com.applovin.sdk.AppLovinSdk;
import org.prebid.mobile.PrebidMobile;
import org.prebid.mobile.rendering.listeners.SdkInitializationListener;

@Keep
public class PrebidMaxMediationAdapter extends MediationAdapterBase implements MaxAdViewAdapter, MaxInterstitialAdapter, MaxRewardedAdapter, MaxNativeAdAdapter {
Expand All @@ -44,8 +45,14 @@ public void initialize(
onCompletionListener.onCompletion(InitializationStatus.INITIALIZED_SUCCESS, null);
} else {
onCompletionListener.onCompletion(InitializationStatus.INITIALIZING, null);
PrebidMobile.setApplicationContext(activity.getApplicationContext(), () -> {
onCompletionListener.onCompletion(InitializationStatus.INITIALIZED_SUCCESS, null);
PrebidMobile.initializeSdk(activity.getApplicationContext(), new SdkInitializationListener() {
@Override
public void onSdkInit() {
onCompletionListener.onCompletion(InitializationStatus.INITIALIZED_SUCCESS, null);
}

@Override
public void onSdkFailedToInit(InitError error) {}
});
}
}
Expand Down
3 changes: 2 additions & 1 deletion PrebidMobile/tests.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ dependencies {

testImplementation 'org.assertj:assertj-core:1.7.0'
testImplementation 'org.skyscreamer:jsonassert:1.5.0'
testImplementation 'com.squareup.okhttp3:mockwebserver:4.9.0'
testImplementation 'com.squareup.okhttp3:mockwebserver:4.9.3'
testImplementation 'com.squareup.okhttp3:okhttp:4.9.3'

testImplementation 'org.apache.commons:commons-lang3:3.7'
testImplementation 'com.google.android.gms:play-services-ads:20.0.0'
Expand Down
Loading

0 comments on commit fc0f441

Please sign in to comment.