diff options
| author | 2024-11-05 09:49:10 +0000 | |
|---|---|---|
| committer | 2024-11-05 10:53:35 +0100 | |
| commit | e94e64001c1781056e0c75f6207658060d2febba (patch) | |
| tree | 0a12a50046c2bdf9e7e4e3eb2e8efcd6256488a9 | |
| parent | 7c65d920b8219de186a3155fb615cb80db87a016 (diff) | |
VirtualDisplay API for brightness callback and default.
Any rate limiting will essentially result in the wrong brightness
passed to the display owner. The callback is ONLY invoked if the
display has an explicit default brightness, in practice there will
only be 1-2 such displays at a time.
Bug: 285020111
Test: presubmit
Test: CTS
Flag: android.companion.virtualdevice.flags.device_aware_display_power
Change-Id: Ie991cfc9a85cbd6711d6c67a6ae5b51ac35f2f59
7 files changed, 130 insertions, 6 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 3fde7497a090..91ce6247d0de 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -5293,13 +5293,19 @@ package android.hardware.display { field public static final int VIRTUAL_DISPLAY_FLAG_TRUSTED = 1024; // 0x400 } + public abstract static class VirtualDisplay.Callback { + method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") public void onRequestedBrightnessChanged(@FloatRange(from=0.0f, to=1.0f) float); + } + public final class VirtualDisplayConfig implements android.os.Parcelable { + method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") @FloatRange(from=0.0f, to=1.0f) public float getDefaultBrightness(); method @FlaggedApi("android.companion.virtualdevice.flags.virtual_display_insets") @Nullable public android.view.DisplayCutout getDisplayCutout(); method @FlaggedApi("android.companion.virtual.flags.vdm_custom_home") public boolean isHomeSupported(); method @FlaggedApi("com.android.window.flags.vdm_force_app_universal_resizable_api") public boolean isIgnoreActivitySizeRestrictions(); } public static final class VirtualDisplayConfig.Builder { + method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setDefaultBrightness(@FloatRange(from=0.0f, to=1.0f) float); method @FlaggedApi("android.companion.virtualdevice.flags.virtual_display_insets") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setDisplayCutout(@Nullable android.view.DisplayCutout); method @FlaggedApi("android.companion.virtual.flags.vdm_custom_home") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setHomeSupported(boolean); method @FlaggedApi("com.android.window.flags.vdm_force_app_universal_resizable_api") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setIgnoreActivitySizeRestrictions(boolean); diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java index 3c6841cd8aeb..56307ae53a0c 100644 --- a/core/java/android/hardware/display/DisplayManagerGlobal.java +++ b/core/java/android/hardware/display/DisplayManagerGlobal.java @@ -1432,6 +1432,13 @@ public final class DisplayManagerGlobal { mExecutor.execute(mCallback::onStopped); } } + + @Override // Binder call + public void onRequestedBrightnessChanged(float brightness) { + if (mCallback != null) { + mExecutor.execute(() -> mCallback.onRequestedBrightnessChanged(brightness)); + } + } } /** diff --git a/core/java/android/hardware/display/IVirtualDisplayCallback.aidl b/core/java/android/hardware/display/IVirtualDisplayCallback.aidl index c3490d177be2..9cc0364f2729 100644 --- a/core/java/android/hardware/display/IVirtualDisplayCallback.aidl +++ b/core/java/android/hardware/display/IVirtualDisplayCallback.aidl @@ -38,4 +38,9 @@ oneway interface IVirtualDisplayCallback { * of the application to release() the virtual display. */ void onStopped(); + + /** + * Called when the virtual display's requested brightness has changed. + */ + void onRequestedBrightnessChanged(float brightness); } diff --git a/core/java/android/hardware/display/VirtualDisplay.java b/core/java/android/hardware/display/VirtualDisplay.java index 32b640583734..3b573ea98c27 100644 --- a/core/java/android/hardware/display/VirtualDisplay.java +++ b/core/java/android/hardware/display/VirtualDisplay.java @@ -16,6 +16,8 @@ package android.hardware.display; import android.annotation.FlaggedApi; +import android.annotation.FloatRange; +import android.annotation.SystemApi; import android.view.Display; import android.view.Surface; @@ -164,5 +166,25 @@ public final class VirtualDisplay { * of the application to release() the virtual display. */ public void onStopped() { } + + /** + * Called when the requested brightness of the display has changed. + * + * <p>The system may adjust the display's brightness based on user or app activity. This + * callback will only be invoked if the display has an explicitly specified default + * brightness value.</p> + * + * <p>Value of {@code 0.0} indicates the minimum supported brightness and value of + * {@code 1.0} indicates the maximum supported brightness.</p> + * + * @see android.view.View#setKeepScreenOn(boolean) + * @see android.view.WindowManager.LayoutParams#screenBrightness + * @see VirtualDisplayConfig.Builder#setDefaultBrightness(float) + * @hide + */ + @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER) + @SystemApi + public void onRequestedBrightnessChanged( + @FloatRange(from = 0.0f, to = 1.0f) float brightness) {} } } diff --git a/core/java/android/hardware/display/VirtualDisplayConfig.java b/core/java/android/hardware/display/VirtualDisplayConfig.java index 49944c76eb99..57d9d28a9d47 100644 --- a/core/java/android/hardware/display/VirtualDisplayConfig.java +++ b/core/java/android/hardware/display/VirtualDisplayConfig.java @@ -29,6 +29,7 @@ import android.media.projection.MediaProjection; import android.os.Handler; import android.os.Parcel; import android.os.Parcelable; +import android.os.PowerManager; import android.util.ArraySet; import android.view.Display; import android.view.DisplayCutout; @@ -61,6 +62,7 @@ public final class VirtualDisplayConfig implements Parcelable { private final boolean mIsHomeSupported; private final DisplayCutout mDisplayCutout; private final boolean mIgnoreActivitySizeRestrictions; + private final float mDefaultBrightness; private VirtualDisplayConfig( @NonNull String name, @@ -76,7 +78,8 @@ public final class VirtualDisplayConfig implements Parcelable { float requestedRefreshRate, boolean isHomeSupported, @Nullable DisplayCutout displayCutout, - boolean ignoreActivitySizeRestrictions) { + boolean ignoreActivitySizeRestrictions, + @FloatRange(from = 0.0f, to = 1.0f) float defaultBrightness) { mName = name; mWidth = width; mHeight = height; @@ -91,6 +94,7 @@ public final class VirtualDisplayConfig implements Parcelable { mIsHomeSupported = isHomeSupported; mDisplayCutout = displayCutout; mIgnoreActivitySizeRestrictions = ignoreActivitySizeRestrictions; + mDefaultBrightness = defaultBrightness; } /** @@ -157,6 +161,22 @@ public final class VirtualDisplayConfig implements Parcelable { } /** + * Returns the default brightness of the display. + * + * <p>Value of {@code 0.0} indicates the minimum supported brightness and value of {@code 1.0} + * indicates the maximum supported brightness.</p> + * + * @see Builder#setDefaultBrightness(float) + * @hide + */ + @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER) + @SystemApi + public @FloatRange(from = 0.0f, to = 1.0f) float getDefaultBrightness() { + return mDefaultBrightness; + } + + + /** * Returns the unique identifier for the display. Shouldn't be displayed to the user. * @hide */ @@ -245,6 +265,7 @@ public final class VirtualDisplayConfig implements Parcelable { dest.writeBoolean(mIsHomeSupported); DisplayCutout.ParcelableWrapper.writeCutoutToParcel(mDisplayCutout, dest, flags); dest.writeBoolean(mIgnoreActivitySizeRestrictions); + dest.writeFloat(mDefaultBrightness); } @Override @@ -272,7 +293,8 @@ public final class VirtualDisplayConfig implements Parcelable { && mRequestedRefreshRate == that.mRequestedRefreshRate && mIsHomeSupported == that.mIsHomeSupported && mIgnoreActivitySizeRestrictions == that.mIgnoreActivitySizeRestrictions - && Objects.equals(mDisplayCutout, that.mDisplayCutout); + && Objects.equals(mDisplayCutout, that.mDisplayCutout) + && mDefaultBrightness == that.mDefaultBrightness; } @Override @@ -281,7 +303,7 @@ public final class VirtualDisplayConfig implements Parcelable { mName, mWidth, mHeight, mDensityDpi, mFlags, mSurface, mUniqueId, mDisplayIdToMirror, mWindowManagerMirroringEnabled, mDisplayCategories, mRequestedRefreshRate, mIsHomeSupported, mDisplayCutout, - mIgnoreActivitySizeRestrictions); + mIgnoreActivitySizeRestrictions, mDefaultBrightness); return hashCode; } @@ -303,6 +325,7 @@ public final class VirtualDisplayConfig implements Parcelable { + " mIsHomeSupported=" + mIsHomeSupported + " mDisplayCutout=" + mDisplayCutout + " mIgnoreActivitySizeRestrictions=" + mIgnoreActivitySizeRestrictions + + " mDefaultBrightness=" + mDefaultBrightness + ")"; } @@ -321,6 +344,7 @@ public final class VirtualDisplayConfig implements Parcelable { mIsHomeSupported = in.readBoolean(); mDisplayCutout = DisplayCutout.ParcelableWrapper.readCutoutFromParcel(in); mIgnoreActivitySizeRestrictions = in.readBoolean(); + mDefaultBrightness = in.readFloat(); } @NonNull @@ -355,6 +379,7 @@ public final class VirtualDisplayConfig implements Parcelable { private boolean mIsHomeSupported = false; private DisplayCutout mDisplayCutout = null; private boolean mIgnoreActivitySizeRestrictions = false; + private float mDefaultBrightness = 0.0f; /** * Creates a new Builder. @@ -547,6 +572,35 @@ public final class VirtualDisplayConfig implements Parcelable { } /** + * Sets the default brightness of the display. + * + * <p>The system will use this brightness value whenever the display should be bright, i.e. + * it is powered on and not dimmed due to user activity or app activity.</p> + * + * <p>Value of {@code 0.0} indicates the minimum supported brightness and value of + * {@code 1.0} indicates the maximum supported brightness.</p> + * + * <p>If unset, defaults to {@code 0.0}</p> + * + * @see android.view.View#setKeepScreenOn(boolean) + * @see Builder#setDefaultBrightness(float) + * @see VirtualDisplay.Callback#onRequestedBrightnessChanged(float) + * @hide + */ + @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER) + @SystemApi + @NonNull + public Builder setDefaultBrightness(@FloatRange(from = 0.0f, to = 1.0f) float brightness) { + if (brightness < PowerManager.BRIGHTNESS_MIN + || brightness > PowerManager.BRIGHTNESS_MAX) { + throw new IllegalArgumentException( + "Virtual display default brightness must be in range [0.0, 1.0]"); + } + mDefaultBrightness = brightness; + return this; + } + + /** * Builds the {@link VirtualDisplayConfig} instance. */ @NonNull @@ -565,7 +619,8 @@ public final class VirtualDisplayConfig implements Parcelable { mRequestedRefreshRate, mIsHomeSupported, mDisplayCutout, - mIgnoreActivitySizeRestrictions); + mIgnoreActivitySizeRestrictions, + mDefaultBrightness); } } } diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java index 421145390190..dabef84fec31 100644 --- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java +++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java @@ -51,6 +51,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.IBinder.DeathRecipient; import android.os.Message; +import android.os.PowerManager; import android.os.RemoteException; import android.os.SystemProperties; import android.util.ArrayMap; @@ -64,6 +65,7 @@ import android.view.SurfaceControl; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.display.brightness.BrightnessUtils; import com.android.server.display.feature.DisplayManagerFlags; import java.io.PrintWriter; @@ -323,7 +325,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter { private int mWidth; private int mHeight; private int mDensityDpi; - private float mRequestedRefreshRate; + private final float mRequestedRefreshRate; private Surface mSurface; private DisplayDeviceInfo mInfo; private int mDisplayState; @@ -332,7 +334,9 @@ public class VirtualDisplayAdapter extends DisplayAdapter { private Display.Mode mMode; private int mDisplayIdToMirror; private boolean mIsWindowManagerMirroring; - private DisplayCutout mDisplayCutout; + private final DisplayCutout mDisplayCutout; + private final float mDefaultBrightness; + private float mCurrentBrightness; public VirtualDisplayDevice(IBinder displayToken, IBinder appToken, int ownerUid, String ownerPackageName, Surface surface, int flags, @@ -349,6 +353,8 @@ public class VirtualDisplayAdapter extends DisplayAdapter { mDensityDpi = virtualDisplayConfig.getDensityDpi(); mRequestedRefreshRate = virtualDisplayConfig.getRequestedRefreshRate(); mDisplayCutout = virtualDisplayConfig.getDisplayCutout(); + mDefaultBrightness = virtualDisplayConfig.getDefaultBrightness(); + mCurrentBrightness = mDefaultBrightness; mMode = createMode(mWidth, mHeight, getRefreshRate()); mSurface = surface; mFlags = flags; @@ -457,6 +463,12 @@ public class VirtualDisplayAdapter extends DisplayAdapter { mCallback.dispatchDisplayResumed(); } } + if (android.companion.virtualdevice.flags.Flags.deviceAwareDisplayPower() + && BrightnessUtils.isValidBrightnessValue(brightnessState) + && brightnessState != mCurrentBrightness) { + mCurrentBrightness = brightnessState; + mCallback.dispatchRequestedBrightnessChanged(mCurrentBrightness); + } return null; } @@ -623,6 +635,10 @@ public class VirtualDisplayAdapter extends DisplayAdapter { mInfo.state = mDisplayState; } + mInfo.brightnessMinimum = PowerManager.BRIGHTNESS_MIN; + mInfo.brightnessMaximum = PowerManager.BRIGHTNESS_MAX; + mInfo.brightnessDefault = mDefaultBrightness; + mInfo.ownerUid = mOwnerUid; mInfo.ownerPackageName = mOwnerPackageName; @@ -642,6 +658,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter { private static final int MSG_ON_DISPLAY_PAUSED = 0; private static final int MSG_ON_DISPLAY_RESUMED = 1; private static final int MSG_ON_DISPLAY_STOPPED = 2; + private static final int MSG_ON_REQUESTED_BRIGHTNESS_CHANGED = 3; private final IVirtualDisplayCallback mCallback; @@ -663,6 +680,9 @@ public class VirtualDisplayAdapter extends DisplayAdapter { case MSG_ON_DISPLAY_STOPPED: mCallback.onStopped(); break; + case MSG_ON_REQUESTED_BRIGHTNESS_CHANGED: + mCallback.onRequestedBrightnessChanged((Float) msg.obj); + break; } } catch (RemoteException e) { Slog.w(TAG, "Failed to notify listener of virtual display event.", e); @@ -677,6 +697,11 @@ public class VirtualDisplayAdapter extends DisplayAdapter { sendEmptyMessage(MSG_ON_DISPLAY_RESUMED); } + public void dispatchRequestedBrightnessChanged(float brightness) { + Message msg = obtainMessage(MSG_ON_REQUESTED_BRIGHTNESS_CHANGED, brightness); + sendMessage(msg); + } + public void dispatchDisplayStopped() { sendEmptyMessage(MSG_ON_DISPLAY_STOPPED); } diff --git a/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java index 3ac7fb0dbe53..e0b0fec380dd 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java @@ -335,6 +335,10 @@ public class VirtualDisplayAdapterTest { @Override public void onStopped() { } + + @Override + public void onRequestedBrightnessChanged(float brightness) { + } }; } } |