Skip to content

Commit cc03c7a

Browse files
authored
Merge pull request #496 from Countly/fix_display_size
fix: size
2 parents ed3d82c + e33e22e commit cc03c7a

File tree

5 files changed

+135
-38
lines changed

5 files changed

+135
-38
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
## 25.4.4
22
* Improved disk size calculation in crash reports.
33

4+
* Mitigated an issue displaying Content on API level 35 and above.
5+
46
## 25.4.3
57
* Improved Health Check metric information.
68
* Improved Content display mechanics.

sdk/src/main/java/ly/count/android/sdk/DeviceInfo.java

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ of this software and associated documentation files (the "Software"), to deal
3939
import android.os.storage.StorageManager;
4040
import android.telephony.TelephonyManager;
4141
import android.util.DisplayMetrics;
42-
import android.view.Display;
43-
import android.view.WindowManager;
4442
import androidx.annotation.NonNull;
4543
import androidx.annotation.Nullable;
4644
import java.io.File;
@@ -131,19 +129,10 @@ public String getResolution(@NonNull final Context context) {
131129
return resolution;
132130
}
133131

134-
/**
135-
* Return the display metrics collected from the WindowManager in the specified context.
136-
* @param context context to use to retrieve the current WindowManager
137-
* @return the display metrics of the current default display
138-
*/
139132
@NonNull
140133
@Override
141134
public DisplayMetrics getDisplayMetrics(@NonNull final Context context) {
142-
final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
143-
final Display display = wm.getDefaultDisplay();
144-
final DisplayMetrics metrics = new DisplayMetrics();
145-
display.getMetrics(metrics);
146-
return metrics;
135+
return UtilsDevice.getDisplayMetrics(context);
147136
}
148137

149138
/**

sdk/src/main/java/ly/count/android/sdk/ModuleContent.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,6 @@ private TransparentActivityConfig extractOrientationPlacements(@NonNull JSONObje
226226
int w = orientationPlacements.optInt("w");
227227
int h = orientationPlacements.optInt("h");
228228
L.d("[ModuleContent] extractOrientationPlacements, orientation: [" + orientation + "], x: [" + x + "], y: [" + y + "], w: [" + w + "], h: [" + h + "]");
229-
230229
TransparentActivityConfig config = new TransparentActivityConfig((int) Math.ceil(x * density), (int) Math.ceil(y * density), (int) Math.ceil(w * density), (int) Math.ceil(h * density));
231230
config.url = content;
232231
return config;

sdk/src/main/java/ly/count/android/sdk/TransparentActivity.java

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@
22

33
import android.annotation.SuppressLint;
44
import android.app.Activity;
5-
import android.content.Context;
65
import android.content.Intent;
76
import android.content.res.Configuration;
87
import android.graphics.Color;
98
import android.net.Uri;
109
import android.os.Bundle;
1110
import android.util.DisplayMetrics;
1211
import android.util.Log;
13-
import android.view.Display;
1412
import android.view.Gravity;
1513
import android.view.View;
1614
import android.view.ViewGroup;
@@ -47,7 +45,6 @@ protected void onCreate(Bundle savedInstanceState) {
4745

4846
// there is a stripe at the top of the screen for contents
4947
// we eliminate it with hiding the system ui
50-
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
5148
super.onCreate(savedInstanceState);
5249
overridePendingTransition(0, 0);
5350

@@ -72,7 +69,7 @@ protected void onCreate(Bundle savedInstanceState) {
7269

7370
// Configure window layout parameters
7471
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
75-
params.gravity = Gravity.TOP | Gravity.LEFT; // try out START
72+
params.gravity = Gravity.TOP | Gravity.START; // try out START
7673
params.x = config.x;
7774
params.y = config.y;
7875
params.height = config.height;
@@ -94,10 +91,7 @@ protected void onCreate(Bundle savedInstanceState) {
9491
}
9592

9693
private TransparentActivityConfig setupConfig(@Nullable TransparentActivityConfig config) {
97-
final WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
98-
final Display display = wm.getDefaultDisplay();
99-
final DisplayMetrics metrics = new DisplayMetrics(); // this gets all
100-
display.getMetrics(metrics);
94+
final DisplayMetrics metrics = UtilsDevice.getDisplayMetrics(this);
10195

10296
if (config == null) {
10397
Log.w(Countly.TAG, "[TransparentActivity] setupConfig, Config is null, using default values with full screen size");
@@ -148,19 +142,39 @@ public void onConfigurationChanged(android.content.res.Configuration newConfig)
148142
currentOrientation = newConfig.orientation;
149143
}
150144

151-
// CHANGE SCREEN SIZE
152-
final WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
153-
final Display display = wm.getDefaultDisplay();
154-
final DisplayMetrics metrics = new DisplayMetrics();
155-
display.getMetrics(metrics);
145+
resizeContent();
146+
}
156147

148+
private void resizeContent() {
149+
// CHANGE SCREEN SIZE
150+
final DisplayMetrics metrics = UtilsDevice.getDisplayMetrics(this);
157151
int scaledWidth = (int) Math.ceil(metrics.widthPixels / metrics.density);
158152
int scaledHeight = (int) Math.ceil(metrics.heightPixels / metrics.density);
159153

160154
// refactor in the future to use the resize_me action
161155
webView.loadUrl("javascript:window.postMessage({type: 'resize', width: " + scaledWidth + ", height: " + scaledHeight + "}, '*');");
162156
}
163157

158+
@Override
159+
public void onDestroy() {
160+
close(new HashMap<>());
161+
162+
if (Countly.sharedInstance().isInitialized()) {
163+
Countly.sharedInstance().moduleContent.notifyAfterContentIsClosed();
164+
}
165+
super.onDestroy();
166+
}
167+
168+
private void hideSystemUI() {
169+
getWindow().getDecorView().setSystemUiVisibility(
170+
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
171+
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
172+
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
173+
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
174+
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
175+
| View.SYSTEM_UI_FLAG_FULLSCREEN);
176+
}
177+
164178
private void resizeContentInternal() {
165179
switch (currentOrientation) {
166180
case Configuration.ORIENTATION_LANDSCAPE:
@@ -274,11 +288,7 @@ private void resizeMeAction(Map<String, Object> query) {
274288
return;
275289
}
276290
try {
277-
final WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
278-
final Display display = wm.getDefaultDisplay();
279-
final DisplayMetrics metrics = new DisplayMetrics();
280-
display.getMetrics(metrics);
281-
291+
final DisplayMetrics metrics = UtilsDevice.getDisplayMetrics(this);
282292
float density = metrics.density;
283293

284294
JSONObject resizeMeJson = (JSONObject) resizeMe;
@@ -414,15 +424,18 @@ private WebView createWebView(TransparentActivityConfig config) {
414424
return false;
415425
}
416426
});
417-
client.afterPageFinished = (closeIt) -> {
418-
if (closeIt) {
419-
close(new HashMap<>());
427+
client.afterPageFinished = new WebViewPageLoadedListener() {
428+
@Override public void onPageLoaded(boolean timedOut) {
429+
if (timedOut) {
430+
close(new HashMap<>());
420431

421-
if (Countly.sharedInstance().isInitialized()) {
422-
Countly.sharedInstance().moduleContent.notifyAfterContentIsClosed();
432+
if (Countly.sharedInstance().isInitialized()) {
433+
Countly.sharedInstance().moduleContent.notifyAfterContentIsClosed();
434+
}
435+
} else {
436+
hideSystemUI();
437+
webView.setVisibility(View.VISIBLE);
423438
}
424-
} else {
425-
webView.setVisibility(View.VISIBLE);
426439
}
427440
};
428441
webView.setWebViewClient(client);
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package ly.count.android.sdk;
2+
3+
import android.annotation.TargetApi;
4+
import android.app.Activity;
5+
import android.content.Context;
6+
import android.graphics.Insets;
7+
import android.graphics.Rect;
8+
import android.os.Build;
9+
import android.util.DisplayMetrics;
10+
import android.view.Display;
11+
import android.view.WindowInsets;
12+
import android.view.WindowManager;
13+
import android.view.WindowMetrics;
14+
import androidx.annotation.NonNull;
15+
16+
class UtilsDevice {
17+
private UtilsDevice() {
18+
}
19+
20+
@NonNull
21+
static DisplayMetrics getDisplayMetrics(@NonNull final Context context) {
22+
final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
23+
final DisplayMetrics metrics = new DisplayMetrics();
24+
25+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
26+
applyWindowMetrics(context, wm, metrics);
27+
} else {
28+
applyLegacyMetrics(wm, metrics);
29+
}
30+
return metrics;
31+
}
32+
33+
@TargetApi(Build.VERSION_CODES.R)
34+
private static void applyWindowMetrics(@NonNull Context context,
35+
@NonNull WindowManager wm,
36+
@NonNull DisplayMetrics outMetrics) {
37+
final WindowMetrics windowMetrics = wm.getCurrentWindowMetrics();
38+
final WindowInsets windowInsets = windowMetrics.getWindowInsets();
39+
40+
// Always respect status bar & cutout (they affect safe area even in fullscreen)
41+
int types = 0;
42+
boolean usePhysicalScreenSize = !(context instanceof Activity);
43+
44+
// If not activity, we can't know system UI visibility, so always use physical screen size
45+
if (!usePhysicalScreenSize) {
46+
// Only subtract navigation bar insets when navigation bar is actually visible
47+
if (windowInsets.isVisible(WindowInsets.Type.navigationBars())) {
48+
types |= WindowInsets.Type.navigationBars();
49+
}
50+
51+
if (windowInsets.isVisible(WindowInsets.Type.statusBars())) {
52+
types |= WindowInsets.Type.statusBars();
53+
}
54+
55+
boolean drawUnderCutout;
56+
WindowManager.LayoutParams params = ((Activity) context).getWindow().getAttributes();
57+
drawUnderCutout = params.layoutInDisplayCutoutMode
58+
== WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
59+
60+
// Only subtract display cutout insets when not allowed to draw under the cutout
61+
if (!drawUnderCutout && windowInsets.isVisible(WindowInsets.Type.displayCutout())) {
62+
types |= WindowInsets.Type.displayCutout();
63+
}
64+
}
65+
66+
// Cutout is always respected as safe area for now even in fullscreen mode
67+
if (windowInsets.isVisible(WindowInsets.Type.displayCutout())) {
68+
types |= WindowInsets.Type.displayCutout();
69+
}
70+
71+
final Insets insets = windowInsets.getInsets(types);
72+
final Rect bounds = windowMetrics.getBounds();
73+
final int width = bounds.width() - insets.left - insets.right;
74+
final int height = bounds.height() - insets.top - insets.bottom;
75+
76+
outMetrics.widthPixels = width;
77+
outMetrics.heightPixels = height;
78+
79+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
80+
outMetrics.density = windowMetrics.getDensity();
81+
} else {
82+
// Fallback: use resource-based density
83+
outMetrics.density = context.getResources().getDisplayMetrics().density;
84+
}
85+
}
86+
87+
@SuppressWarnings("deprecation")
88+
private static void applyLegacyMetrics(@NonNull WindowManager wm,
89+
@NonNull DisplayMetrics outMetrics) {
90+
final Display display = wm.getDefaultDisplay();
91+
display.getRealMetrics(outMetrics);
92+
//getMetrics gives us size minus navigation bar
93+
}
94+
}

0 commit comments

Comments
 (0)