Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .run/All Tests.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,6 @@
<option name="ENABLED" value="true" />
<option name="INCLUDE" value="false" />
</pattern>
<pattern>
<option name="PATTERN" value="com.clevertap.android.sdk.inapp.InAppWebViewClient" />
<option name="ENABLED" value="true" />
<option name="INCLUDE" value="false" />
</pattern>
<pattern>
<option name="PATTERN" value="com.clevertap.android.sdk.inapp.CTInAppWebView" />
<option name="ENABLED" value="true" />
Expand Down Expand Up @@ -160,6 +155,11 @@
<option name="ENABLED" value="true" />
<option name="INCLUDE" value="false" />
</pattern>
<pattern>
<option name="PATTERN" value="com.clevertap.android.sdk.inapp.CTInAppHtmlBannerOverlay" />
<option name="ENABLED" value="true" />
<option name="INCLUDE" value="false" />
</pattern>
<pattern>
<option name="PATTERN" value="com.clevertap.android.*" />
<option name="ENABLED" value="true" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import android.os.Bundle;
import android.webkit.JavascriptInterface;

import androidx.annotation.RestrictTo;
import com.clevertap.android.sdk.inapp.CTInAppAction;
import com.clevertap.android.sdk.inapp.fragment.CTInAppBaseFragment;
import com.clevertap.android.sdk.inapp.CTInAppHost;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -18,12 +20,13 @@
@SuppressWarnings("WeakerAccess")
public class CTWebInterface {

private WeakReference<CleverTapAPI> cleverTapWr = new WeakReference<>(null);
private final WeakReference<CleverTapAPI> cleverTapWr;

private WeakReference<CTInAppBaseFragment> fragmentWr = new WeakReference<>(null);
private final WeakReference<CTInAppHost> hostWr;

public CTWebInterface(CleverTapAPI instance) {
this.cleverTapWr = new WeakReference<>(instance);
cleverTapWr = new WeakReference<>(instance);
hostWr = new WeakReference<>(null);
CleverTapAPI cleverTapAPI = cleverTapWr.get();
if (cleverTapAPI != null) {
CoreState coreState = cleverTapAPI.getCoreState();
Expand All @@ -34,9 +37,9 @@ public CTWebInterface(CleverTapAPI instance) {
}

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public CTWebInterface(CleverTapAPI instance, CTInAppBaseFragment inAppBaseFragment) {
this.cleverTapWr = new WeakReference<>(instance);
this.fragmentWr = new WeakReference<>(inAppBaseFragment);
public CTWebInterface(CleverTapAPI instance, CTInAppHost host) {
cleverTapWr = new WeakReference<>(instance);
hostWr = new WeakReference<>(host);
}

/**
Expand Down Expand Up @@ -65,9 +68,9 @@ public void dismissInAppNotification() {
Logger.d("CleverTap Instance is null.");
} else {
//Dismisses current IAM and proceeds to call promptForPushPermission()
CTInAppBaseFragment fragment = fragmentWr.get();
if (fragment != null) {
fragment.didDismiss(null);
CTInAppHost host = hostWr.get();
if (host != null) {
host.didDismissInApp(null);
}
}
}
Expand Down Expand Up @@ -404,9 +407,9 @@ public void triggerInAppAction(String actionJson, String callToAction, String bu
return;
}

CTInAppBaseFragment fragment = fragmentWr.get();
if (fragment == null) {
Logger.d("CTWebInterface Fragment is null");
CTInAppHost host = hostWr.get();
if (host == null) {
Logger.d("CTWebInterface host is null");
return;
}

Expand All @@ -427,7 +430,7 @@ public void triggerInAppAction(String actionJson, String callToAction, String bu
actionData.putString("button_id", buttonId);
}

fragment.triggerAction(action, callToAction, actionData);
host.triggerAction(action, callToAction, actionData);
} catch (JSONException je) {
Logger.d("CTWebInterface invalid action JSON: " + actionJson);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package com.clevertap.android.sdk.inapp

import android.content.Context
import android.os.Bundle
import android.util.TypedValue
import com.clevertap.android.sdk.CleverTapInstanceConfig
import com.clevertap.android.sdk.Constants
import com.clevertap.android.sdk.utils.UriHelper
import java.lang.ref.WeakReference
import java.net.URLDecoder
import kotlin.text.split

internal class CTInAppHost(
inAppListener: InAppListener?,
private val config: CleverTapInstanceConfig,
private val inAppNotification: CTInAppNotification,
private var callbacks: Callbacks?,
context: Context?
) {

internal interface Callbacks {
fun onDismissInApp()
}

private var inAppListenerWeakReference = WeakReference(inAppListener)
private val contextWeakReference = WeakReference(context)

fun getInAppListener(): InAppListener? {
val listener = inAppListenerWeakReference.get()
if (listener == null) {
config.logger.verbose(
config.accountId,
"InAppListener is null for notification: ${inAppNotification.jsonDescription}"
)
}
return listener
}

fun setInAppListener(listener: InAppListener) {
inAppListenerWeakReference = WeakReference(listener)
}

fun getScaledPixels(raw: Int): Int {
val context = contextWeakReference.get()
if (context == null) {
return raw
}
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
raw.toFloat(),
context.resources.displayMetrics
).toInt()
}

fun triggerAction(
action: CTInAppAction, callToAction: String?, additionalData: Bundle?
) {
var additionalData = additionalData
var action = action
var callToAction = callToAction
if (action.type == InAppActionType.OPEN_URL) {
//All URL parameters should be tracked as additional data
val urlActionData = UriHelper.getAllKeyValuePairs(action.actionUrl, false)

// callToAction is handled as a parameter
var callToActionUrlParam = urlActionData.getString(Constants.KEY_C2A)
// no need to keep it in the data bundle
urlActionData.remove(Constants.KEY_C2A)

// add all additional params, overriding the url params if there is a collision
if (additionalData != null) {
urlActionData.putAll(additionalData)
}
// Use the merged data for the action
additionalData = urlActionData
if (callToActionUrlParam != null) {
// check if there is a deeplink within the callToAction param
val parts = callToActionUrlParam.split(Constants.URL_PARAM_DL_SEPARATOR)
if (parts.size == 2) {
// Decode it here as it is not decoded by UriHelper
try {
// Extract the actual callToAction value
callToActionUrlParam = URLDecoder.decode(parts[0], "UTF-8")
} catch (e: Exception) {
config.logger.debug("Error parsing c2a param", e)
}
// use the url from the callToAction param
action = CTInAppAction.CREATOR.createOpenUrlAction(parts[1])
}
}
if (callToAction == null) {
// Use the url param value only if no other value is passed
callToAction = callToActionUrlParam
}
}
val actionData = notifyActionTriggered(action, callToAction ?: "", additionalData)
didDismissInApp(actionData)
}

fun openUrl(url: String) {
triggerAction(CTInAppAction.CREATOR.createOpenUrlAction(url), null, null)
}

fun didDismissInApp(data: Bundle?) {
callbacks?.onDismissInApp()
getInAppListener()?.inAppNotificationDidDismiss(inAppNotification, data)
}

fun didShowInApp(data: Bundle?) {
getInAppListener()?.inAppNotificationDidShow(inAppNotification, data)
}

fun notifyActionTriggered(
action: CTInAppAction, callToAction: String, additionalData: Bundle?
): Bundle? {
return getInAppListener()?.inAppNotificationActionTriggered(
inAppNotification, action, callToAction, additionalData, contextWeakReference.get()
)
}
}
Loading