Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

staging -> main (core v2.6.0) #590

Merged
merged 10 commits into from
Nov 16, 2023
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
Loading