Add additional native resolution options on Android 10+ with display insets included

Fixes #956
Fixes #986
This commit is contained in:
Cameron Gutman
2021-06-22 23:56:45 -05:00
parent f187e57899
commit 394ce458a0
3 changed files with 62 additions and 7 deletions
+22 -2
View File
@@ -214,9 +214,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
prefConfig = PreferenceConfiguration.readPreferences(this); prefConfig = PreferenceConfiguration.readPreferences(this);
tombstonePrefs = Game.this.getSharedPreferences("DecoderTombstone", 0); tombstonePrefs = Game.this.getSharedPreferences("DecoderTombstone", 0);
if (prefConfig.stretchVideo) { if (prefConfig.stretchVideo || shouldIgnoreInsetsForResolution(prefConfig.width, prefConfig.height)) {
// Allow the activity to layout under notches if the fill-screen option // Allow the activity to layout under notches if the fill-screen option
// was turned on by the user // was turned on by the user or it's a full-screen native resolution
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
getWindow().getAttributes().layoutInDisplayCutoutMode = getWindow().getAttributes().layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
@@ -627,6 +627,26 @@ public class Game extends Activity implements SurfaceHolder.Callback,
Math.round(refreshRate) % prefConfig.fps <= 3; Math.round(refreshRate) % prefConfig.fps <= 3;
} }
private boolean shouldIgnoreInsetsForResolution(int width, int height) {
// Never ignore insets for non-native resolutions
if (!PreferenceConfiguration.isNativeResolution(width, height)) {
return false;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Display display = getWindowManager().getDefaultDisplay();
for (Display.Mode candidate : display.getSupportedModes()) {
// Ignore insets if this is an exact match for the display resolution
if ((width == candidate.getPhysicalWidth() && height == candidate.getPhysicalHeight()) ||
(height == candidate.getPhysicalWidth() && width == candidate.getPhysicalHeight())) {
return true;
}
}
}
return false;
}
private float prepareDisplayForRendering() { private float prepareDisplayForRendering() {
Display display = getWindowManager().getDefaultDisplay(); Display display = getWindowManager().getDefaultDisplay();
WindowManager.LayoutParams windowLayoutParams = getWindow().getAttributes(); WindowManager.LayoutParams windowLayoutParams = getWindow().getAttributes();
@@ -19,6 +19,7 @@ import android.preference.PreferenceScreen;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Range; import android.util.Range;
import android.view.Display; import android.view.Display;
import android.view.DisplayCutout;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -79,10 +80,20 @@ public class StreamSettings extends Activity {
pref.setValue(value); pref.setValue(value);
} }
private void addNativeResolutionEntry(int nativeWidth, int nativeHeight) { private void addNativeResolutionEntry(int nativeWidth, int nativeHeight, boolean insetsRemoved) {
ListPreference pref = (ListPreference) findPreference(PreferenceConfiguration.RESOLUTION_PREF_STRING); ListPreference pref = (ListPreference) findPreference(PreferenceConfiguration.RESOLUTION_PREF_STRING);
String newName = getResources().getString(R.string.resolution_prefix_native) + " ("+nativeWidth+"x"+nativeHeight+")"; String newName;
if (insetsRemoved) {
newName = getResources().getString(R.string.resolution_prefix_native_fullscreen);
}
else {
newName = getResources().getString(R.string.resolution_prefix_native);
}
newName += " ("+nativeWidth+"x"+nativeHeight+")";
String newValue = nativeWidth+"x"+nativeHeight; String newValue = nativeWidth+"x"+nativeHeight;
CharSequence[] values = pref.getEntryValues(); CharSequence[] values = pref.getEntryValues();
@@ -221,6 +232,29 @@ public class StreamSettings extends Activity {
int maxSupportedResW = 0; int maxSupportedResW = 0;
// Add a native resolution with any insets included for users that don't want content
// behind the notch of their display
boolean hasInsets = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// FIXME: Come up with a solution for Android 9 which doesn't support Display.getCutout()
DisplayCutout cutout = display.getCutout();
if (cutout != null) {
DisplayMetrics metrics = new DisplayMetrics();
int widthInsets = cutout.getSafeInsetLeft() + cutout.getSafeInsetRight();
int heightInsets = cutout.getSafeInsetBottom() + cutout.getSafeInsetTop();
if (widthInsets != 0 || heightInsets != 0) {
getActivity().getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
int width = Math.max(metrics.widthPixels - widthInsets, metrics.heightPixels - heightInsets);
int height = Math.min(metrics.widthPixels - widthInsets, metrics.heightPixels - heightInsets);
addNativeResolutionEntry(width, height, false);
hasInsets = true;
}
}
}
// Always allow resolutions that are smaller or equal to the active // Always allow resolutions that are smaller or equal to the active
// display resolution because decoders can report total non-sense to us. // display resolution because decoders can report total non-sense to us.
// For example, a p201 device reports: // For example, a p201 device reports:
@@ -240,7 +274,7 @@ public class StreamSettings extends Activity {
// unless they report greater than 4K resolutions. // unless they report greater than 4K resolutions.
if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEVISION) || if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEVISION) ||
(width > 3840 || height > 2160)) { (width > 3840 || height > 2160)) {
addNativeResolutionEntry(width, height); addNativeResolutionEntry(width, height, hasInsets);
} }
if ((width >= 3840 || height >= 2160) && maxSupportedResW < 3840) { if ((width >= 3840 || height >= 2160) && maxSupportedResW < 3840) {
@@ -350,7 +384,7 @@ public class StreamSettings extends Activity {
getActivity().getWindowManager().getDefaultDisplay().getRealMetrics(metrics); getActivity().getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
int width = Math.max(metrics.widthPixels, metrics.heightPixels); int width = Math.max(metrics.widthPixels, metrics.heightPixels);
int height = Math.min(metrics.widthPixels, metrics.heightPixels); int height = Math.min(metrics.widthPixels, metrics.heightPixels);
addNativeResolutionEntry(width, height); addNativeResolutionEntry(width, height, false);
} }
else { else {
// On Android 4.1, we have to resort to reflection to invoke hidden APIs // On Android 4.1, we have to resort to reflection to invoke hidden APIs
@@ -361,7 +395,7 @@ public class StreamSettings extends Activity {
Method getRawWidthFunc = Display.class.getMethod("getRawWidth"); Method getRawWidthFunc = Display.class.getMethod("getRawWidth");
int width = (Integer) getRawWidthFunc.invoke(display); int width = (Integer) getRawWidthFunc.invoke(display);
int height = (Integer) getRawHeightFunc.invoke(display); int height = (Integer) getRawHeightFunc.invoke(display);
addNativeResolutionEntry(Math.max(width, height), Math.min(width, height)); addNativeResolutionEntry(Math.max(width, height), Math.min(width, height), false);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
+1
View File
@@ -154,6 +154,7 @@
<string name="suffix_seekbar_bitrate_mbps">Mbps</string> <string name="suffix_seekbar_bitrate_mbps">Mbps</string>
<string name="title_checkbox_stretch_video">Stretch video to full-screen</string> <string name="title_checkbox_stretch_video">Stretch video to full-screen</string>
<string name="resolution_prefix_native">Native</string> <string name="resolution_prefix_native">Native</string>
<string name="resolution_prefix_native_fullscreen">Native Full-Screen</string>
<string name="category_audio_settings">Audio Settings</string> <string name="category_audio_settings">Audio Settings</string>
<string name="title_audio_config_list">Surround sound configuration</string> <string name="title_audio_config_list">Surround sound configuration</string>