Skip to content

Extract an action handler for FIAM clicks #4729

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,14 @@
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.net.Uri;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.browser.customtabs.CustomTabsIntent;
import com.google.firebase.FirebaseApp;
import com.google.firebase.inappmessaging.FirebaseInAppMessaging;
import com.google.firebase.inappmessaging.FirebaseInAppMessagingDisplayCallbacks;
Expand Down Expand Up @@ -96,6 +92,8 @@ public class FirebaseInAppMessagingDisplay extends FirebaseInAppMessagingDisplay
private FiamListener fiamListener;
private InAppMessage inAppMessage;
private FirebaseInAppMessagingDisplayCallbacks callbacks;
private FirebaseInAppMessagingDisplayActionHandler actionHandler =
new FirebaseInAppMessagingDisplayDefaultActionHandler();

@VisibleForTesting @Nullable String currentlyBoundActivityName;

Expand Down Expand Up @@ -167,6 +165,13 @@ public void clearFiamListener() {
this.fiamListener = null;
}

/**
* Sets the action handler used when one of the message elements is clicked.
*/
public void setActionHandler(@NonNull FirebaseInAppMessagingDisplayActionHandler actionHandler) {
this.actionHandler = actionHandler;
}

/**
* Bind FIAM listener on Activity resume.
*
Expand Down Expand Up @@ -324,7 +329,7 @@ public void onClick(View v) {
Logging.logi("Calling callback for click action");
callbacks.messageClicked(action);
}
launchUriIntent(activity, Uri.parse(action.getActionUrl()));
actionHandler.handleAction(activity, action);
notifyFiamClick();
// Ensure that we remove the displayed FIAM, and ensure that on re-load, the message
// isn't re-displayed
Expand Down Expand Up @@ -540,43 +545,4 @@ private void notifyFiamDismiss() {
fiamListener.onFiamDismiss();
}
}

private void launchUriIntent(Activity activity, Uri uri) {
if (ishttpOrHttpsUri(uri) && supportsCustomTabs(activity)) {
// If we can launch a chrome view, try that.
CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder().build();
Intent intent = customTabsIntent.intent;
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
customTabsIntent.launchUrl(activity, uri);
} else {
// If we can't launch a chrome view try to launch anything that can handle a URL.
Intent browserIntent = new Intent(Intent.ACTION_VIEW, uri);
ResolveInfo info = activity.getPackageManager().resolveActivity(browserIntent, 0);
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (info != null) {
activity.startActivity(browserIntent);
} else {
// If the device can't resolve a url then log, but don't crash.
Logging.loge("Device cannot resolve intent for: " + Intent.ACTION_VIEW);
}
}
}

private boolean supportsCustomTabs(Activity activity) {
Intent customTabIntent = new Intent("android.support.customtabs.action.CustomTabsService");
customTabIntent.setPackage("com.android.chrome");
List<ResolveInfo> resolveInfos =
activity.getPackageManager().queryIntentServices(customTabIntent, 0);
return resolveInfos != null && !resolveInfos.isEmpty();
}

private boolean ishttpOrHttpsUri(Uri uri) {
if (uri == null) {
return false;
}
String scheme = uri.getScheme();
return scheme != null && (scheme.equalsIgnoreCase("http") || scheme.equalsIgnoreCase("https"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.google.firebase.inappmessaging.display;

import android.app.Activity;
import androidx.annotation.NonNull;
import com.google.firebase.inappmessaging.model.Action;

/**
* Handles message element (image, button) clicks.
*/
public interface FirebaseInAppMessagingDisplayActionHandler {
void handleAction(@NonNull Activity activity, @NonNull Action action);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.google.firebase.inappmessaging.display;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.browser.customtabs.CustomTabsIntent;
import com.google.firebase.inappmessaging.display.internal.Logging;
import com.google.firebase.inappmessaging.model.Action;
import java.util.List;

/**
* The default handler of message actions. It opens a Custom Tab with the link if possible or tries to find an Activity
* that can handle the action URL
*/
public class FirebaseInAppMessagingDisplayDefaultActionHandler implements FirebaseInAppMessagingDisplayActionHandler {
@Override
public void handleAction(@NonNull Activity activity, @NonNull Action action) {
Uri uri = Uri.parse(action.getActionUrl());
if (ishttpOrHttpsUri(uri) && supportsCustomTabs(activity)) {
// If we can launch a chrome view, try that.
CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder().build();
Intent intent = customTabsIntent.intent;
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
customTabsIntent.launchUrl(activity, uri);
} else {
// If we can't launch a chrome view try to launch anything that can handle a URL.
Intent browserIntent = new Intent(Intent.ACTION_VIEW, uri);
ResolveInfo info = activity.getPackageManager().resolveActivity(browserIntent, 0);
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (info != null) {
activity.startActivity(browserIntent);
} else {
// If the device can't resolve a url then log, but don't crash.
Logging.loge("Device cannot resolve intent for: " + Intent.ACTION_VIEW);
}
}
}

private boolean supportsCustomTabs(Activity activity) {
Intent customTabIntent = new Intent("android.support.customtabs.action.CustomTabsService");
customTabIntent.setPackage("com.android.chrome");
List<ResolveInfo> resolveInfos =
activity.getPackageManager().queryIntentServices(customTabIntent, 0);
return !resolveInfos.isEmpty();
}

private boolean ishttpOrHttpsUri(Uri uri) {
if (uri == null) {
return false;
}
String scheme = uri.getScheme();
return scheme != null && (scheme.equalsIgnoreCase("http") || scheme.equalsIgnoreCase("https"));
}
}