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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]
### Fixed
- In-app messages now match the host app's system bar behavior instead of overriding it. This fixes fullscreen in-apps drawing content behind the status bar.

## [3.6.5]
### Fixed
- Fixed IterableEmbeddedView not having an empty constructor and causing crashes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
Expand All @@ -16,8 +14,6 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.OrientationEventListener;
Expand All @@ -35,6 +31,7 @@
import androidx.core.graphics.ColorUtils;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.DialogFragment;

Expand Down Expand Up @@ -78,6 +75,7 @@
private boolean shouldAnimate;
private double inAppBackgroundAlpha;
private String inAppBackgroundColor;
private boolean hostIsEdgeToEdge;

public static IterableInAppFragmentHTMLNotification createInstance(@NonNull String htmlString, boolean callbackOnCancel, @NonNull IterableHelper.IterableUrlCallback clickCallback, @NonNull IterableInAppLocation location, @NonNull String messageId, @NonNull Double backgroundAlpha, @NonNull Rect padding) {
return IterableInAppFragmentHTMLNotification.createInstance(htmlString, callbackOnCancel, clickCallback, location, messageId, backgroundAlpha, padding, false, new IterableInAppMessage.InAppBgColor(null, 0.0f));
Expand Down Expand Up @@ -176,13 +174,8 @@
applyWindowGravity(dialog.getWindow(), "onCreateDialog");
}

if (getInAppLayout(insetPadding) == InAppLayout.FULLSCREEN) {
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else if (getInAppLayout(insetPadding) != InAppLayout.TOP) {
// For TOP layout in-app, status bar will be opaque so that the in-app content does not overlap with translucent status bar.
// For other non-fullscreen in-apps layouts (BOTTOM and CENTER), status bar will be translucent
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
hostIsEdgeToEdge = isHostActivityEdgeToEdge();
configureSystemBarBehavior(dialog.getWindow());
return dialog;
}

Expand All @@ -191,10 +184,6 @@
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

if (getInAppLayout(insetPadding) == InAppLayout.FULLSCREEN) {
getDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}

// Set initial window gravity based on inset padding (only for non-fullscreen)
if (getInAppLayout(insetPadding) != InAppLayout.FULLSCREEN) {
applyWindowGravity(getDialog().getWindow(), "onCreateView");
Expand Down Expand Up @@ -295,9 +284,7 @@
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Handle edge-to-edge insets with modern approach (only for non-fullscreen)
// Full screen in-apps should not have padding from system bars
if (getInAppLayout(insetPadding) != InAppLayout.FULLSCREEN) {
if (getInAppLayout(insetPadding) != InAppLayout.FULLSCREEN && hostIsEdgeToEdge) {
ViewCompat.setOnApplyWindowInsetsListener(view, (v, insets) -> {
Insets sysBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(0, sysBars.top, 0, sysBars.bottom);
Expand Down Expand Up @@ -600,30 +587,11 @@
return;
}

DisplayMetrics displayMetrics = activity.getResources().getDisplayMetrics();
Window window = notification.getDialog().getWindow();
Rect insetPadding = notification.insetPadding;

WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();

// Get the correct screen size based on api level
// https://stackoverflow.com/questions/35780980/getting-the-actual-screen-height-android
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
display.getRealSize(size);
} else {
display.getSize(size);
}

int webViewWidth = size.x;
int webViewHeight = size.y;

//Check if the dialog is full screen
if (insetPadding.bottom == 0 && insetPadding.top == 0) {
//Handle full screen
window.setLayout(webViewWidth, webViewHeight);
getDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
} else {
// Resize the WebView directly with explicit size
float relativeHeight = height * getResources().getDisplayMetrics().density;
Expand Down Expand Up @@ -710,6 +678,56 @@
}
}

private void configureSystemBarBehavior(Window window) {
if (window == null) return;
Activity activity = getActivity();
if (activity == null || activity.getWindow() == null) return;

if (hostIsEdgeToEdge) {
WindowCompat.setDecorFitsSystemWindows(window, false);
window.setStatusBarColor(Color.TRANSPARENT);
window.setNavigationBarColor(Color.TRANSPARENT);
} else {
window.setStatusBarColor(activity.getWindow().getStatusBarColor());
window.setNavigationBarColor(activity.getWindow().getNavigationBarColor());
}
}

private boolean isHostActivityEdgeToEdge() {
Activity activity = getActivity();
if (activity == null || activity.getWindow() == null) return false;

if (hasEdgeToEdgeLegacyFlags(activity)) {
return true;
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return isContentDrawnBehindSystemBars(activity);
}

return false;
}

private boolean hasEdgeToEdgeLegacyFlags(Activity activity) {
int flags = activity.getWindow().getDecorView().getSystemUiVisibility();
return (flags & View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) != 0;
}

private boolean isContentDrawnBehindSystemBars(Activity activity) {
View contentView = activity.findViewById(android.R.id.content);
if (contentView == null) return false;

int contentTop = getViewTopPositionInWindow(contentView);
boolean statusBarPushesContentDown = contentTop > 0;
return !statusBarPushesContentDown;
}

private int getViewTopPositionInWindow(View view) {
int[] position = new int[2];
view.getLocationInWindow(position);
return position[1];
}

/**
* Sets the window gravity based on inset padding
*
Expand Down
Loading