In normal circumstances this is as easy as calling.
mDecorView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
@Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
WindowInsets finalInsets = v.onApplyWindowInsets(insets);
DisplayCutout cutout = finalInsets.getDisplayCutout();
// handling
adjustGameLayout(cutout);
return finalInsets;
}
});
The crucial part is that the application is in fact a game, and we're crossing into the problem of the custom game launcher (Samsung with its Game Boosters, LG with its own game launcher, and possibly many other vendors have something similar).
What is a game launcher?
It's software added by vendors, that can recognize games and manipulate runtime settings to get better performance/to reduce battery usage.
They can manipulate properties like: refresh rate or game resolution (independently from screen resolution). They tend to recognize games by package id.
Here is the problem
Devices now support different screen resolutions, For instance, Samsung Note 10+ supports: 1520x720, 2280x1080, and 3040x1440, and that's fine: we're getting correct cutouts values according to the resolution selected.
But the cutout metrics are not adjusted accordingly to the resolution reduced by the Game Launcher (it can reduce the resolution even to 1/3 of the currently selected resolution). As a result of which, let's say the user selected 2280x1080 (when the top cutout should be 75) and on top of that game launcher reduces the resolution to 1140x540. Then if a game will try to layout game elements according to the cutout data (75) we're getting twice the required offset.
At that moment the cutouts data isn't providing the expected values.
How this could be mitigated?
There are some methods to correct the cutout data. What's needed is to calculate the scale ratio set by the game launcher (ofc there is no API for this - game is oblivion it's running under the launcher). Here we need to face the Android fragmentation problem. The obvious way is to get the current screen resolution - right?
This can be read by getWindowManager().getDefaultDisplay().getMode()
- the problem is: Samsung (Note 10+) on Android 9/10 returns always the top available mode in the display settings - regardless of what user selected. (LG G7 @ Android 10 works fine though).
Other ideas to calculate the ratio are:
- getting the dimension of
status_bar_height
- and this is promising so far. getWindowManager().getCurrentWindowMetrics()
- also promising, but at the moment my trust level that this will work across all vendors isn't impressive.
TL;DR;
How we can get correct cutout data, that includes game launcher down-scaling?
Edit
I know we're not the only ones affected - I tested the top 20 games. Therefore you might don't know you're affected.