Skip to content

Commit

Permalink
Merge pull request #590 from adobe/staging
Browse files Browse the repository at this point in the history
  • Loading branch information
praveek authored Nov 16, 2023
2 parents f7c1e4a + 65b082a commit 5f6f0c0
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 102 deletions.
1 change: 1 addition & 0 deletions code/core/api/core.api
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,7 @@ public class com/adobe/marketing/mobile/services/ui/MessageFragment : android/ap
public fun onActivityCreated (Landroid/os/Bundle;)V
public fun onAttach (Landroid/content/Context;)V
public fun onCreate (Landroid/os/Bundle;)V
public fun onCreateDialog (Landroid/os/Bundle;)Landroid/app/Dialog;
public fun onDestroyView ()V
public fun onDetach ()V
public fun onTouch (Landroid/view/View;Landroid/view/MotionEvent;)Z
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ package com.adobe.marketing.mobile.internal

internal object CoreConstants {
const val LOG_TAG = "MobileCore"
const val VERSION = "2.5.1"
const val VERSION = "2.6.0"

object EventDataKeys {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public enum MessageGesture {
SWIPE_DOWN("swipeDown"),
SWIPE_LEFT("swipeLeft"),
SWIPE_RIGHT("swipeRight"),
BACKGROUND_TAP("backgroundTap");
BACKGROUND_TAP("tapBackground");

private String name;
private static final Map<String, MessageGesture> gestureStringToGestureEnumMap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

package com.adobe.marketing.mobile.services.ui;

import android.app.Activity;
import android.app.Dialog;
import android.app.FragmentTransaction;
import android.content.Context;
Expand All @@ -25,6 +26,7 @@
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.cardview.widget.CardView;
import androidx.fragment.app.DialogFragment;
Expand Down Expand Up @@ -172,7 +174,66 @@ public void onCreate(final Bundle savedInstanceState) {
.getApplicationContext(),
webViewGestureListener);

setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Translucent_NoTitleBar);
setStyle(DialogFragment.STYLE_NO_FRAME, android.R.style.Theme_Translucent_NoTitleBar);
}

@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
final Activity parentActivity = getActivity();
final int fragmentTheme = getTheme();
final Dialog defaultDialog = super.onCreateDialog(savedInstanceState);

if (parentActivity == null || message == null) {
Log.trace(
ServiceConstants.LOG_TAG,
TAG,
"%s (%s), returning a default Dialog object.",
parentActivity == null ? "Parent Activity" : "Message",
UNEXPECTED_NULL_VALUE);
return defaultDialog;
}

final MessageSettings messageSettings = message.getMessageSettings();
if (messageSettings == null) {
Log.trace(
ServiceConstants.LOG_TAG,
TAG,
"%s (MessageSettings), returning a default Dialog object.",
UNEXPECTED_NULL_VALUE);
return defaultDialog;
}

final boolean uiTakeoverEnabled = messageSettings.getUITakeover();
return new Dialog(parentActivity, fragmentTheme) {
@Override
public boolean onTouchEvent(@NonNull final MotionEvent motionEvent) {
if (!uiTakeoverEnabled) {
// only log action up or down events as this logging can get quite
// spammy
if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
Log.trace(
ServiceConstants.LOG_TAG,
TAG,
"UI takeover is false, passing the touch event to the parent"
+ " activity.");
}
return parentActivity.dispatchTouchEvent(motionEvent);
} else {
// load any behavior url strings on action up only as a touch consists of
// two motion events: an action down and an action up event
if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
Log.trace(
ServiceConstants.LOG_TAG,
TAG,
"UI takeover is true, parent activity UI is inaccessible."
+ " Processing defined background tap behaviors.");
webViewGestureListener.handleGesture(MessageGesture.BACKGROUND_TAP);
return true;
}
}
return super.onTouchEvent(motionEvent);
}
};
}

@Override
Expand Down Expand Up @@ -234,13 +295,14 @@ public void onDetach() {

@Override
public boolean onTouch(final View view, final MotionEvent motionEvent) {
final String viewName = view.getClass().getSimpleName();
if (message == null) {
Log.debug(
ServiceConstants.LOG_TAG,
TAG,
"%s (AEPMessage), unable to handle the touch event on %s.",
UNEXPECTED_NULL_VALUE,
view.getClass().getSimpleName());
viewName);
return true;
}

Expand All @@ -251,7 +313,7 @@ public boolean onTouch(final View view, final MotionEvent motionEvent) {
TAG,
"%s (WebView), unable to handle the touch event on %s.",
UNEXPECTED_NULL_VALUE,
view.getClass().getSimpleName());
viewName);
return true;
}

Expand All @@ -262,37 +324,7 @@ public boolean onTouch(final View view, final MotionEvent motionEvent) {
TAG,
"%s (MessageSettings), unable to handle the touch event on %s.",
UNEXPECTED_NULL_VALUE,
view.getClass().getSimpleName());
return true;
}

final int motionEventAction = motionEvent.getAction();

// determine if the tap occurred outside the webview
if ((motionEventAction == MotionEvent.ACTION_DOWN
|| motionEventAction == MotionEvent.ACTION_BUTTON_PRESS)
&& view.getId() != webView.getId()) {
Log.trace(
ServiceConstants.LOG_TAG,
TAG,
"Detected tap on %s",
view.getClass().getSimpleName());

final boolean uiTakeoverEnabled = messageSettings.getUITakeover();

// if ui takeover is false, dismiss the message
if (!uiTakeoverEnabled) {
Log.trace(
ServiceConstants.LOG_TAG,
TAG,
"UI takeover is false, dismissing the message.");
webViewGestureListener.handleGesture(MessageGesture.BACKGROUND_TAP);
// perform the tap to allow interaction with ui elements outside the webview
return view.onTouchEvent(motionEvent);
}

// ui takeover is true, consume the tap and ignore it
Log.trace(ServiceConstants.LOG_TAG, TAG, "UI takeover is true, ignoring the tap.");
viewName);
return true;
}

Expand Down Expand Up @@ -343,10 +375,6 @@ private void addListeners() {

final Dialog dialog = getDialog();
if (dialog != null) {
// set this fragment onTouchListener to dismiss the IAM if a touch occurs on the decor
// view
dialog.getWindow().getDecorView().setOnTouchListener(this);

// handle on back pressed to dismiss the message
dialog.setOnKeyListener(
(dialogInterface, keyCode, event) -> {
Expand All @@ -368,7 +396,6 @@ private void removeListeners() {

final Dialog dialog = getDialog();
if (dialog != null) {
dialog.getWindow().getDecorView().setOnTouchListener(null);
dialog.setOnKeyListener(null);
}
}
Expand All @@ -395,6 +422,16 @@ private void applyBackdropColor() {
return;
}

final boolean uiTakeoverEnabled = messageSettings.getUITakeover();
// we don't want to dim the background if ui takeover is disabled
if (!uiTakeoverEnabled) {
Log.trace(
ServiceConstants.LOG_TAG,
TAG,
"Not applying background alpha, ui takeover is disabled.");
return;
}

final Dialog dialog = getDialog();

if (dialog != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import androidx.cardview.widget.CardView;
import com.adobe.marketing.mobile.services.Log;
import com.adobe.marketing.mobile.services.ServiceConstants;
import com.adobe.marketing.mobile.services.ui.MessageSettings.MessageAnimation;
import com.adobe.marketing.mobile.services.ui.MessageSettings.MessageGesture;
import com.adobe.marketing.mobile.util.StringUtils;

Expand Down Expand Up @@ -114,24 +113,15 @@ public boolean onFling(
}

/**
* Generates a dismiss animation using the {@link ObjectAnimator}. The {@link
* Generates a dismiss animation if needed using the {@link ObjectAnimator}. The {@link
* androidx.cardview.widget.CardView} frame will be dismissed at the direction of the detected
* swipe {@link MessageGesture}. If the in-app message was dismissed via a {@code
* MessageGesture.BACKGROUND_TAP} then the {@code CardView} will be dismissed using the
* dismissal {@link MessageAnimation} specified in the {@link MessageSettings}.
* swipe {@link MessageGesture}. Background tap gestures will not dismiss the message but any
* associated behavior will be
*
* @param gesture The detected swipe {@code MessageGesture} that occurred.
*/
public void handleGesture(final MessageGesture gesture) {
if (gesture.equals(MessageSettings.MessageGesture.BACKGROUND_TAP)) {
// we are handling a background tap. message will be dismissed via the dismiss animation
// specified in the MessageSettings.
dismissMessage(gesture, false);
return;
}

final AEPMessage message = parentFragment.getAEPMessage();

if (message == null) {
Log.debug(
ServiceConstants.LOG_TAG,
Expand Down Expand Up @@ -163,7 +153,21 @@ public void handleGesture(final MessageGesture gesture) {
webViewFrame.getTop(),
-message.parentViewHeight);
break;
default: // default, dismiss to bottom if not a background tap
case BACKGROUND_TAP:
animation = null;
// we are handling a background tap. handle the background tap interaction behavior
// specified (if any).
// if we have no defined background tap behavior then we do not want to dismiss the
// message.
final String behavior =
parentFragment.gestures == null
? null
: parentFragment.gestures.get(gesture);
if (!StringUtils.isNullOrEmpty(behavior)) {
message.listener.overrideUrlLoad(message, behavior);
}
break;
default: // default, dismiss to bottom
animation =
ObjectAnimator.ofFloat(
webViewFrame, "y", webViewFrame.getTop(), message.parentViewHeight);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import kotlin.test.assertTrue
@RunWith(MockitoJUnitRunner.Silent::class)
class MobileCoreTests {

private var EXTENSION_VERSION = "2.5.1"
private var EXTENSION_VERSION = "2.6.0"

@Mock
private lateinit var mockedEventHub: EventHub
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ import kotlin.test.assertTrue
@RunWith(MockitoJUnitRunner.Silent::class)
class ConfigurationExtensionTests {

private var EXTENSION_VERSION = "2.5.1"
private var EXTENSION_VERSION = "2.6.0"

@Mock
private lateinit var mockServiceProvider: ServiceProvider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,47 +148,4 @@ public void testOnTouchListener_MessageIsNull_ThenTouchEventIsIgnored() {
ArgumentMatchers.any(AEPMessage.class), ArgumentMatchers.anyString());
Assert.assertTrue(eventProcessed);
}

@Test
public void
testOnTouchListener_TouchOccurredOutsideWebview_And_UITakeoverFalse_ThenMessageDismissed() {
// setup
messageFragment.webViewGestureListener = mockWebViewGestureListener;
messageFragment.gestureDetector = mockGestureDetector;
Mockito.when(mockAEPMessageSettings.getUITakeover()).thenReturn(false);
Mockito.when(mockWebView.getId()).thenReturn(12345);
Mockito.when(mockViewGroup.getId()).thenReturn(67890);
Mockito.when(mockAEPMessage.getWebView()).thenReturn(mockWebView);
// call onCreate to setup the gestures
messageFragment.onCreate(mockSavedInstanceState);
// test
boolean eventProcessed = messageFragment.onTouch(mockViewGroup, mockMotionEvent);
// verify
Mockito.verify(mockFullscreenMessageDelegate, Mockito.times(1))
.overrideUrlLoad(
ArgumentMatchers.any(AEPMessage.class), ArgumentMatchers.anyString());
// expect false because the touch event was handled by the rootview
Assert.assertFalse(eventProcessed);
}

@Test
public void
testOnTouchListener_TouchOccurredOutsideWebview_And_UITakeoverTrue_ThenMessageNotDismissed() {
// setup
messageFragment.webViewGestureListener = mockWebViewGestureListener;
messageFragment.gestureDetector = mockGestureDetector;
Mockito.when(mockAEPMessageSettings.getUITakeover()).thenReturn(true);
Mockito.when(mockWebView.getId()).thenReturn(12345);
Mockito.when(mockViewGroup.getId()).thenReturn(67890);
Mockito.when(mockAEPMessage.getWebView()).thenReturn(mockWebView);
// call onCreate to setup the gestures
messageFragment.onCreate(mockSavedInstanceState);
// test
boolean eventProcessed = messageFragment.onTouch(mockViewGroup, mockMotionEvent);
// verify
Mockito.verify(mockFullscreenMessageDelegate, Mockito.times(0))
.overrideUrlLoad(
ArgumentMatchers.any(AEPMessage.class), ArgumentMatchers.anyString());
Assert.assertTrue(eventProcessed);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,8 @@ public void testOnFling_VerticalSwipeDown_And_FlingVelocityOverThreshold_Then_Me
}

@Test
public void testHandleGesture_BackgroundTap_Then_MessageDismissed() {
public void
testHandleGesture_BackgroundTap_BackgroundTapBehaviorDefined_Then_MessageDismissed() {
// setup
Mockito.when(mockMotionEvent.getX()).thenReturn(0f);
Mockito.when(mockMotionEvent2.getX()).thenReturn(0f);
Expand All @@ -262,4 +263,23 @@ public void testHandleGesture_BackgroundTap_Then_MessageDismissed() {
.overrideUrlLoad(
ArgumentMatchers.any(AEPMessage.class), ArgumentMatchers.anyString());
}

@Test
public void
testHandleGesture_BackgroundTap_BackgroundTapBehaviorNotDefined_Then_MessageNotDismissed() {
// setup
gestureMap.remove(MessageGesture.BACKGROUND_TAP);
mockMessageFragment.gestures = gestureMap;
Mockito.when(mockMotionEvent.getX()).thenReturn(0f);
Mockito.when(mockMotionEvent2.getX()).thenReturn(0f);
Mockito.when(mockMotionEvent.getY()).thenReturn(0f);
Mockito.when(mockMotionEvent2.getY()).thenReturn(-300.0f);
// test
gestureListener.handleGesture(MessageGesture.BACKGROUND_TAP);
// verify
Assert.assertFalse(mockMessageFragment.isDismissedWithGesture());
Mockito.verify(mockFullscreenMessageDelegate, Mockito.times(0))
.overrideUrlLoad(
ArgumentMatchers.any(AEPMessage.class), ArgumentMatchers.anyString());
}
}
2 changes: 1 addition & 1 deletion code/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ android.useAndroidX=true
#
#Maven artifacts
#Core extension
coreExtensionVersion=2.5.1
coreExtensionVersion=2.6.0
coreExtensionName=core
coreExtensionAARName=core-phone-release.aar
coreMavenRepoName=AdobeMobileCoreSdk
Expand Down

0 comments on commit 5f6f0c0

Please sign in to comment.