diff --git a/api/current.txt b/api/current.txt index 75fd86b2abf8a..1beddd45d652c 100644 --- a/api/current.txt +++ b/api/current.txt @@ -1062,6 +1062,7 @@ package android { field public static final int popupWindowStyle = 16842870; // 0x1010076 field public static final int port = 16842793; // 0x1010029 field public static final int positiveButtonText = 16843253; // 0x10101f5 + field public static final int preferMinimalPostProcessing = 16844300; // 0x101060c field public static final int preferenceCategoryStyle = 16842892; // 0x101008c field public static final int preferenceFragmentStyle = 16844038; // 0x1010506 field public static final int preferenceInformationStyle = 16842893; // 0x101008d @@ -11192,6 +11193,7 @@ package android.content.pm { field public String parentActivityName; field public String permission; field public int persistableMode; + field public boolean preferMinimalPostProcessing; field public int screenOrientation; field public int softInputMode; field public String targetActivity; @@ -49904,6 +49906,7 @@ package android.view { method @Deprecated public float[] getSupportedRefreshRates(); method @Deprecated public int getWidth(); method public boolean isHdr(); + method public boolean isMinimalPostProcessingSupported(); method public boolean isValid(); method public boolean isWideColorGamut(); field public static final int DEFAULT_DISPLAY = 0; // 0x0 @@ -52936,6 +52939,7 @@ package android.view { method public abstract void setNavigationBarColor(@ColorInt int); method public void setNavigationBarContrastEnforced(boolean); method public void setNavigationBarDividerColor(@ColorInt int); + method public void setPreferMinimalPostProcessing(boolean); method public void setReenterTransition(android.transition.Transition); method public abstract void setResizingCaptionDrawable(android.graphics.drawable.Drawable); method public final void setRestrictedCaptionAreaListener(android.view.Window.OnRestrictedCaptionAreaChangedListener); @@ -53323,6 +53327,7 @@ package android.view { field public int layoutInDisplayCutoutMode; field @Deprecated public int memoryType; field public String packageName; + field public boolean preferMinimalPostProcessing; field public int preferredDisplayModeId; field @Deprecated public float preferredRefreshRate; field public int rotationAnimation; diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 3f012997fe1ac..070a4f80d4e21 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -7882,6 +7882,7 @@ public class Activity extends ContextThemeWrapper mCurrentConfig = config; mWindow.setColorMode(info.colorMode); + mWindow.setPreferMinimalPostProcessing(info.preferMinimalPostProcessing); setAutofillOptions(application.getAutofillOptions()); setContentCaptureOptions(application.getContentCaptureOptions()); diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 5b1f92642ee2b..e5daaca4aa528 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -289,6 +289,34 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { @ColorMode public int colorMode = COLOR_MODE_DEFAULT; + /** + * Indicates whether the activity wants the connected display to do minimal post processing on + * the produced image or video frames. This will only be requested if this activity's main + * window is visible on the screen. + * + *
This setting should be used when low latency has a higher priority than image enhancement + * processing (e.g. for games or video conferencing). + * + *
If the Display sink is connected via HDMI, the device will begin to send infoframes with + * Auto Low Latency Mode enabled and Game Content Type. This will switch the connected display + * to a minimal image processing mode (if available), which reduces latency, improving the user + * experience for gaming or video conferencing applications. For more information, see HDMI 2.1 + * specification. + * + *
If the Display sink has an internal connection or uses some other protocol than HDMI, + * effects may be similar but implementation-defined. + * + *
The ability to switch to a mode with minimal post proessing may be disabled by a user + * setting in the system settings menu. In that case, this field is ignored and the display will + * remain in its current mode. + * + *
Set from attribute {@link android.R.attr#preferMinimalPostProcessing}. + * + * @see android.view.WindowManager.LayoutParams#preferMinimalPostProcessing + * @see android.view.Display#isMinimalPostProcessingSupported + */ + public boolean preferMinimalPostProcessing = false; + /** * Bit in {@link #flags} indicating whether this activity is able to * run in multiple processes. If @@ -1004,6 +1032,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { requestedVrComponent = orig.requestedVrComponent; rotationAnimation = orig.rotationAnimation; colorMode = orig.colorMode; + preferMinimalPostProcessing = orig.preferMinimalPostProcessing; maxAspectRatio = orig.maxAspectRatio; minAspectRatio = orig.minAspectRatio; } @@ -1231,6 +1260,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { dest.writeInt(colorMode); dest.writeFloat(maxAspectRatio); dest.writeFloat(minAspectRatio); + dest.writeBoolean(preferMinimalPostProcessing); } /** @@ -1349,6 +1379,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { colorMode = source.readInt(); maxAspectRatio = source.readFloat(); minAspectRatio = source.readFloat(); + preferMinimalPostProcessing = source.readBoolean(); } /** diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java index c9551378c1908..79a339fa27aab 100644 --- a/core/java/android/hardware/display/DisplayManagerInternal.java +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -24,7 +24,6 @@ import android.util.IntArray; import android.util.SparseArray; import android.view.Display; import android.view.DisplayInfo; -import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; @@ -151,11 +150,15 @@ public abstract class DisplayManagerInternal { * has a preference. * @param requestedModeId The preferred mode id for the top-most visible window that has a * preference. + * @param requestedMinimalPostProcessing The preferred minimal post processing setting for the + * display. This is true when there is at least one visible window that wants minimal post + * processng on. * @param inTraversal True if called from WindowManagerService during a window traversal * prior to call to performTraversalInTransactionFromWindowManager. */ public abstract void setDisplayProperties(int displayId, boolean hasContent, - float requestedRefreshRate, int requestedModeId, boolean inTraversal); + float requestedRefreshRate, int requestedModeId, boolean requestedMinimalPostProcessing, + boolean inTraversal); /** * Applies an offset to the contents of a display, for example to avoid burn-in. diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index b555d20bc08a4..4368115917e54 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -21,6 +21,7 @@ import static android.Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE; import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.SuppressLint; import android.annotation.TestApi; import android.app.KeyguardManager; import android.compat.annotation.UnsupportedAppUsage; @@ -875,6 +876,31 @@ public final class Display { } } + /** + *
Returns true if the connected display can be switched into a mode with minimal + * post processing.
+ * + *If the Display sink is connected via HDMI, this method will return true if the + * display supports either Auto Low Latency Mode or Game Content Type. + * + *
If the Display sink has an internal connection or uses some other protocol than + * HDMI, this method will return true if the sink can be switched into an + * implementation-defined low latency image processing mode.
+ * + *The ability to switch to a mode with minimal post processing may be disabled + * by a user setting in the system settings menu. In that case, this method returns + * false.
+ * + * @see android.view.Window#setPreferMinimalPostProcessing + */ + @SuppressLint("VisiblySynchronized") + public boolean isMinimalPostProcessingSupported() { + synchronized (this) { + updateDisplayInfoLocked(); + return mDisplayInfo.minimalPostProcessingSupported; + } + } + /** * Request the display applies a color mode. * @hide diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index 8a5385d6e2b2d..7d455c93729cc 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -183,6 +183,14 @@ public final class DisplayInfo implements Parcelable { /** The display's HDR capabilities */ public Display.HdrCapabilities hdrCapabilities; + /** + * Indicates whether the display can be switched into a mode with minimal post + * processing. + * + * @see android.view.Display#isMinimalPostProcessingSupported + */ + public boolean minimalPostProcessingSupported; + /** * The logical display density which is the basis for density-independent * pixels. @@ -305,6 +313,7 @@ public final class DisplayInfo implements Parcelable { && colorMode == other.colorMode && Arrays.equals(supportedColorModes, other.supportedColorModes) && Objects.equals(hdrCapabilities, other.hdrCapabilities) + && minimalPostProcessingSupported == other.minimalPostProcessingSupported && logicalDensityDpi == other.logicalDensityDpi && physicalXDpi == other.physicalXDpi && physicalYDpi == other.physicalYDpi @@ -346,6 +355,7 @@ public final class DisplayInfo implements Parcelable { supportedColorModes = Arrays.copyOf( other.supportedColorModes, other.supportedColorModes.length); hdrCapabilities = other.hdrCapabilities; + minimalPostProcessingSupported = other.minimalPostProcessingSupported; logicalDensityDpi = other.logicalDensityDpi; physicalXDpi = other.physicalXDpi; physicalYDpi = other.physicalYDpi; @@ -388,6 +398,7 @@ public final class DisplayInfo implements Parcelable { supportedColorModes[i] = source.readInt(); } hdrCapabilities = source.readParcelable(null); + minimalPostProcessingSupported = source.readBoolean(); logicalDensityDpi = source.readInt(); physicalXDpi = source.readFloat(); physicalYDpi = source.readFloat(); @@ -430,6 +441,7 @@ public final class DisplayInfo implements Parcelable { dest.writeInt(supportedColorModes[i]); } dest.writeParcelable(hdrCapabilities, flags); + dest.writeBoolean(minimalPostProcessingSupported); dest.writeInt(logicalDensityDpi); dest.writeFloat(physicalXDpi); dest.writeFloat(physicalYDpi); diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 069d5378d2c81..f6d6522f80d60 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -169,6 +169,8 @@ public final class SurfaceControl implements Parcelable { private static native int nativeGetActiveColorMode(IBinder displayToken); private static native boolean nativeSetActiveColorMode(IBinder displayToken, int colorMode); + private static native void nativeSetAutoLowLatencyMode(IBinder displayToken, boolean on); + private static native void nativeSetGameContentType(IBinder displayToken, boolean on); private static native void nativeSetDisplayPowerMode( IBinder displayToken, int mode); private static native void nativeDeferTransactionUntil(long transactionObj, long nativeObject, @@ -186,6 +188,9 @@ public final class SurfaceControl implements Parcelable { private static native Display.HdrCapabilities nativeGetHdrCapabilities(IBinder displayToken); + private static native boolean nativeGetAutoLowLatencyModeSupport(IBinder displayToken); + private static native boolean nativeGetGameContentTypeSupport(IBinder displayToken); + private static native void nativeSetInputWindowInfo(long transactionObj, long nativeObject, InputWindowHandle handle); @@ -1686,6 +1691,28 @@ public final class SurfaceControl implements Parcelable { return colorSpaces; } + /** + * @hide + */ + public static void setAutoLowLatencyMode(IBinder displayToken, boolean on) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + + nativeSetAutoLowLatencyMode(displayToken, on); + } + + /** + * @hide + */ + public static void setGameContentType(IBinder displayToken, boolean on) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + + nativeSetGameContentType(displayToken, on); + } + /** * @hide */ @@ -1737,6 +1764,28 @@ public final class SurfaceControl implements Parcelable { return nativeGetHdrCapabilities(displayToken); } + /** + * @hide + */ + public static boolean getAutoLowLatencyModeSupport(IBinder displayToken) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + + return nativeGetAutoLowLatencyModeSupport(displayToken); + } + + /** + * @hide + */ + public static boolean getGameContentTypeSupport(IBinder displayToken) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + + return nativeGetGameContentTypeSupport(displayToken); + } + /** * @hide */ diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 07764694a40b0..a1894f30d6f69 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -1198,6 +1198,44 @@ public abstract class Window { dispatchWindowAttributesChanged(attrs); } + /** + * If {@code isPreferred} is true, this method requests that the connected display does minimal + * post processing when this window is visible on the screen. Otherwise, it requests that the + * display switches back to standard image processing. + * + *By default, the display does not do minimal post processing and if this is desired, this + * method should not be used. It should be used with {@code isPreferred=true} when low + * latency has a higher priority than image enhancement processing (e.g. for games or video + * conferencing). The display will automatically go back into standard image processing mode + * when no window requesting minimal posst processing is visible on screen anymore. + * {@code setPreferMinimalPostProcessing(false)} can be used if + * {@code setPreferMinimalPostProcessing(true)} was previously called for this window and + * minimal post processing is no longer required. + * + *
If the Display sink is connected via HDMI, the device will begin to send infoframes with + * Auto Low Latency Mode enabled and Game Content Type. This will switch the connected display + * to a minimal image processing mode (if available), which reduces latency, improving the user + * experience for gaming or video conferencing applications. For more information, see HDMI 2.1 + * specification. + * + *
If the Display sink has an internal connection or uses some other protocol than HDMI, + * effects may be similar but implementation-defined. + * + *
The ability to switch to a mode with minimal post proessing may be disabled by a user + * setting in the system settings menu. In that case, this method does nothing. + * + * @see android.content.pm.ActivityInfo#preferMinimalPostProcessing + * @see android.view.Display#isMinimalPostProcessingSupported + * @see android.view.WindowManager.LayoutParams#preferMinimalPostProcessing + * + * @param isPreferred Indicates whether minimal post processing is preferred for this window + * ({@code isPreferred=true}) or not ({@code isPreferred=false}). + */ + public void setPreferMinimalPostProcessing(boolean isPreferred) { + mWindowAttributes.preferMinimalPostProcessing = isPreferred; + dispatchWindowAttributesChanged(mWindowAttributes); + } + /** * Returns the requested color mode of the window, one of * {@link ActivityInfo#COLOR_MODE_DEFAULT}, {@link ActivityInfo#COLOR_MODE_WIDE_COLOR_GAMUT} diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index fc126396edc68..f7d9706a9fcee 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -2606,6 +2606,33 @@ public interface WindowManager extends ViewManager { @UnsupportedAppUsage public long hideTimeoutMilliseconds = -1; + /** + * Indicates whether this window wants the connected display to do minimal post processing + * on the produced image or video frames. This will only be requested if the window is + * visible on the screen. + * + *
This setting should be used when low latency has a higher priority than image + * enhancement processing (e.g. for games or video conferencing). + * + *
If the Display sink is connected via HDMI, the device will begin to send infoframes + * with Auto Low Latency Mode enabled and Game Content Type. This will switch the connected + * display to a minimal image processing mode (if available), which reduces latency, + * improving the user experience for gaming or video conferencing applications. For more + * information, see HDMI 2.1 specification. + * + *
If the Display sink has an internal connection or uses some other protocol than HDMI, + * effects may be similar but implementation-defined. + * + *
The ability to switch to a mode with minimal post proessing may be disabled by a user
+ * setting in the system settings menu. In that case, this field is ignored and the display
+ * will remain in its current mode.
+ *
+ * @see android.content.pm.ActivityInfo#preferMinimalPostProcessing
+ * @see android.view.Display#isMinimalPostProcessingSupported
+ * @see android.view.Window#setPreferMinimalPostProcessing
+ */
+ public boolean preferMinimalPostProcessing = false;
+
/**
* The color mode requested by this window. The target display may
* not be able to honor the request. When the color mode is not set
@@ -2909,6 +2936,7 @@ public interface WindowManager extends ViewManager {
out.writeInt(mFitWindowInsetsTypes);
out.writeInt(mFitWindowInsetsSides);
out.writeBoolean(mFitIgnoreVisibility);
+ out.writeBoolean(preferMinimalPostProcessing);
}
public static final @android.annotation.NonNull Parcelable.Creator