mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Extend physical display size workaround for ATVs
Extend Sony workaround up to and including Oreo. Due to a platform issue the Display API couldn't report 1080p UI and 4k SurfaceView support until Oreo. Since Oreo it is still common for devices to misreport their display sizes via Display, so this change switches to using system properties up to and including Pie. On Pie treble may prevent writing sys.display-size so check for vendor.display-size instead. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=214987203
This commit is contained in:
parent
5c8dabade6
commit
5d5b641c1d
@ -18,7 +18,6 @@ package com.google.android.exoplayer2.audio;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.media.MediaCodec;
|
||||
import android.media.MediaCrypto;
|
||||
import android.media.MediaFormat;
|
||||
@ -707,21 +706,12 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
* be determined.
|
||||
*/
|
||||
private int getCodecMaxInputSize(MediaCodecInfo codecInfo, Format format) {
|
||||
if (Util.SDK_INT < 24 && "OMX.google.raw.decoder".equals(codecInfo.name)) {
|
||||
// OMX.google.raw.decoder didn't resize its output buffers correctly prior to N, so there's no
|
||||
// point requesting a non-default input size. Doing so may cause a native crash, where-as not
|
||||
// doing so will cause a more controlled failure when attempting to fill an input buffer. See:
|
||||
// https://github.com/google/ExoPlayer/issues/4057.
|
||||
boolean needsRawDecoderWorkaround = true;
|
||||
if (Util.SDK_INT == 23) {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
if (packageManager != null
|
||||
&& packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
|
||||
// The workaround is not required for AndroidTV devices running M.
|
||||
needsRawDecoderWorkaround = false;
|
||||
}
|
||||
}
|
||||
if (needsRawDecoderWorkaround) {
|
||||
if ("OMX.google.raw.decoder".equals(codecInfo.name)) {
|
||||
// OMX.google.raw.decoder didn't resize its output buffers correctly prior to N, except on
|
||||
// Android TV running M, so there's no point requesting a non-default input size. Doing so may
|
||||
// cause a native crash, whereas not doing so will cause a more controlled failure when
|
||||
// attempting to fill an input buffer. See: https://github.com/google/ExoPlayer/issues/4057.
|
||||
if (Util.SDK_INT < 24 && !(Util.SDK_INT == 23 && Util.isAndroidTv(context))) {
|
||||
return Format.NO_VALUE;
|
||||
}
|
||||
}
|
||||
|
@ -1728,6 +1728,18 @@ public final class Util {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the device is an Android TV.
|
||||
*
|
||||
* @param context Any context.
|
||||
* @return Whether the device is an Android TV.
|
||||
*/
|
||||
public static boolean isAndroidTv(Context context) {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
return packageManager != null
|
||||
&& packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the physical size of the default display, in pixels.
|
||||
*
|
||||
@ -1747,43 +1759,42 @@ public final class Util {
|
||||
* @return The physical display size, in pixels.
|
||||
*/
|
||||
public static Point getPhysicalDisplaySize(Context context, Display display) {
|
||||
if (Util.SDK_INT < 25 && display.getDisplayId() == Display.DEFAULT_DISPLAY) {
|
||||
// Before API 25 the Display object does not provide a working way to identify Android TVs
|
||||
// that can show 4k resolution in a SurfaceView, so check for supported devices here.
|
||||
if ("Sony".equals(Util.MANUFACTURER) && Util.MODEL.startsWith("BRAVIA")
|
||||
if (Util.SDK_INT <= 28
|
||||
&& display.getDisplayId() == Display.DEFAULT_DISPLAY
|
||||
&& Util.isAndroidTv(context)) {
|
||||
// On Android TVs it is common for the UI to be configured for a lower resolution than
|
||||
// SurfaceViews can output. Before API 26 the Display object does not provide a way to
|
||||
// identify this case, and up to and including API 28 many devices still do not correctly set
|
||||
// their hardware compositor output size.
|
||||
|
||||
// Sony Android TVs advertise support for 4k output via a system feature.
|
||||
if ("Sony".equals(Util.MANUFACTURER)
|
||||
&& Util.MODEL.startsWith("BRAVIA")
|
||||
&& context.getPackageManager().hasSystemFeature("com.sony.dtv.hardware.panel.qfhd")) {
|
||||
return new Point(3840, 2160);
|
||||
} else if (("NVIDIA".equals(Util.MANUFACTURER) && Util.MODEL.contains("SHIELD"))
|
||||
|| ("philips".equals(Util.toLowerInvariant(Util.MANUFACTURER))
|
||||
&& (Util.MODEL.startsWith("QM1")
|
||||
|| Util.MODEL.equals("QV151E")
|
||||
|| Util.MODEL.equals("TPM171E")))) {
|
||||
// Attempt to read sys.display-size.
|
||||
String sysDisplaySize = null;
|
||||
}
|
||||
|
||||
// Otherwise check the system property for display size. From API 28 treble may prevent the
|
||||
// system from writing sys.display-size so we check vendor.display-size instead.
|
||||
String displaySize =
|
||||
Util.SDK_INT < 28
|
||||
? getSystemProperty("sys.display-size")
|
||||
: getSystemProperty("vendor.display-size");
|
||||
// If we managed to read the display size, attempt to parse it.
|
||||
if (!TextUtils.isEmpty(displaySize)) {
|
||||
try {
|
||||
@SuppressLint("PrivateApi")
|
||||
Class<?> systemProperties = Class.forName("android.os.SystemProperties");
|
||||
Method getMethod = systemProperties.getMethod("get", String.class);
|
||||
sysDisplaySize = (String) getMethod.invoke(systemProperties, "sys.display-size");
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Failed to read sys.display-size", e);
|
||||
}
|
||||
// If we managed to read sys.display-size, attempt to parse it.
|
||||
if (!TextUtils.isEmpty(sysDisplaySize)) {
|
||||
try {
|
||||
String[] sysDisplaySizeParts = split(sysDisplaySize.trim(), "x");
|
||||
if (sysDisplaySizeParts.length == 2) {
|
||||
int width = Integer.parseInt(sysDisplaySizeParts[0]);
|
||||
int height = Integer.parseInt(sysDisplaySizeParts[1]);
|
||||
if (width > 0 && height > 0) {
|
||||
return new Point(width, height);
|
||||
}
|
||||
String[] displaySizeParts = split(displaySize.trim(), "x");
|
||||
if (displaySizeParts.length == 2) {
|
||||
int width = Integer.parseInt(displaySizeParts[0]);
|
||||
int height = Integer.parseInt(displaySizeParts[1]);
|
||||
if (width > 0 && height > 0) {
|
||||
return new Point(width, height);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// Do nothing.
|
||||
}
|
||||
Log.e(TAG, "Invalid sys.display-size: " + sysDisplaySize);
|
||||
} catch (NumberFormatException e) {
|
||||
// Do nothing.
|
||||
}
|
||||
Log.e(TAG, "Invalid display size: " + displaySize);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1800,6 +1811,19 @@ public final class Util {
|
||||
return displaySize;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getSystemProperty(String name) {
|
||||
try {
|
||||
@SuppressLint("PrivateApi")
|
||||
Class<?> systemProperties = Class.forName("android.os.SystemProperties");
|
||||
Method getMethod = systemProperties.getMethod("get", String.class);
|
||||
return (String) getMethod.invoke(systemProperties, name);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Failed to read system property " + name, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(23)
|
||||
private static void getDisplaySizeV23(Display display, Point outSize) {
|
||||
Display.Mode mode = display.getMode();
|
||||
|
Loading…
x
Reference in New Issue
Block a user