Loading core/java/android/window/flags/windowing_frontend.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -524,3 +524,13 @@ flag { description: "Use a single binder for task-org/transition messaging to shell" bug: "410930250" } flag { name: "screen_brightness_dim_on_emulator" namespace: "wear_systems" description: "Apply screen brightness to emulator display overlay" bug: "418830217" metadata { purpose: PURPOSE_BUGFIX } } core/res/res/values/config.xml +3 −0 Original line number Diff line number Diff line Loading @@ -3869,6 +3869,9 @@ should show a display overlay on the screen --> <bool name="config_windowEnableCircularEmulatorDisplayOverlay">false</bool> <!-- Whether the emulator shows screen brightness dim in the overlay. --> <bool name="config_windowEnableScreenBrightnessEmulatorDisplayOverlay">false</bool> <!-- Defines the default set of global actions. Actions may still be disabled or hidden based on the current state of the device. Each item must be one of the following strings: Loading core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -407,6 +407,7 @@ <java-symbol type="bool" name="config_windowShowCircularMask" /> <java-symbol type="bool" name="config_predictShowStartingSurface" /> <java-symbol type="bool" name="config_windowEnableCircularEmulatorDisplayOverlay" /> <java-symbol type="bool" name="config_windowEnableScreenBrightnessEmulatorDisplayOverlay" /> <java-symbol type="bool" name="config_supportMicNearUltrasound" /> <java-symbol type="bool" name="config_supportSpeakerNearUltrasound" /> <java-symbol type="bool" name="config_supportAudioSourceUnprocessed" /> Loading services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java +114 −13 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.wm; import static android.hardware.display.DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; Loading @@ -27,16 +29,25 @@ import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.hardware.display.BrightnessInfo; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerGlobal; import android.util.Slog; import android.view.Display; import android.view.Surface; import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl; class EmulatorDisplayOverlay { import com.android.internal.annotations.VisibleForTesting; class EmulatorDisplayOverlay implements DisplayManager.DisplayListener { private static final String TAG = TAG_WITH_CLASS_NAME ? "EmulatorDisplayOverlay" : TAG_WM; private static final String TITLE = "EmulatorDisplayOverlay"; private static final float FALLBACK_BRIGHTNESS = 1.0f; private static final int MAX_OVERLAY_ALPHA = 0xFF; // Display dimensions private Point mScreenSize; Loading @@ -44,6 +55,10 @@ class EmulatorDisplayOverlay { private final Surface mSurface; private final BLASTBufferQueue mBlastBufferQueue; private final WindowManagerService mWmService; private final int mDisplayId; private final boolean mEnableScreenBrightnessDim; private int mLastDW; private int mLastDH; private boolean mDrawNeeded; Loading @@ -51,8 +66,19 @@ class EmulatorDisplayOverlay { private int mRotation; private boolean mVisible; EmulatorDisplayOverlay(Context context, DisplayContent dc, int zOrder, SurfaceControl.Transaction t) { private float mScreenBrightness; EmulatorDisplayOverlay(Context context, WindowManagerService wmService, DisplayContent dc, int zOrder, SurfaceControl.Transaction t, boolean enableCircularOverlay, boolean enableScreenBrightnessDim) { this(context, wmService, dc, zOrder, t, enableCircularOverlay, enableScreenBrightnessDim, new BLASTBufferQueue(TITLE, /* updateDestinationFrame */ true)); } @VisibleForTesting EmulatorDisplayOverlay(Context context, WindowManagerService wmService, DisplayContent dc, int zOrder, SurfaceControl.Transaction t, boolean enableCircularOverlay, boolean enableScreenBrightnessDim, BLASTBufferQueue blastBufferQueue) { final Display display = dc.getDisplay(); mScreenSize = new Point(); display.getSize(mScreenSize); Loading @@ -74,16 +100,30 @@ class EmulatorDisplayOverlay { } mSurfaceControl = ctrl; mDrawNeeded = true; mOverlay = context.getDrawable( com.android.internal.R.drawable.emulator_circular_window_overlay); mOverlay = enableCircularOverlay ? context.getDrawable( com.android.internal.R.drawable.emulator_circular_window_overlay) : null; mBlastBufferQueue = new BLASTBufferQueue(TITLE, /* updateDestinationFrame */ true); mBlastBufferQueue = blastBufferQueue; mBlastBufferQueue.update(mSurfaceControl, mScreenSize.x, mScreenSize.y, PixelFormat.RGBA_8888); mSurface = mBlastBufferQueue.createSurface(); mWmService = wmService; mDisplayId = dc.getDisplayId(); mEnableScreenBrightnessDim = enableScreenBrightnessDim; if (enableScreenBrightnessDim) { updateScreenBrightness(mDisplayId); DisplayManagerGlobal.getInstance().registerDisplayListener( this, null, INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED, context.getPackageName() ); } } private void drawIfNeeded(SurfaceControl.Transaction t) { private void drawIfNeeded() { if (!mDrawNeeded || !mVisible) { return; } Loading @@ -97,15 +137,29 @@ class EmulatorDisplayOverlay { if (c == null) { return; } c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.SRC); t.setPosition(mSurfaceControl, 0, 0); c.drawColor(getBackgroundColor(), PorterDuff.Mode.SRC); // Always draw the overlay with square dimensions int size = Math.max(mScreenSize.x, mScreenSize.y); if (mOverlay != null) { mOverlay.setBounds(0, 0, size, size); mOverlay.draw(c); } mSurface.unlockCanvasAndPost(c); } private int getBackgroundColor() { if (mEnableScreenBrightnessDim) { return getScreenBrightnessDimColor(); } else { return Color.TRANSPARENT; } } private int getScreenBrightnessDimColor() { int alpha = Math.round((1.0f - mScreenBrightness) * MAX_OVERLAY_ALPHA); return (alpha << 24) | 0x000000; } // Note: caller responsible for being inside // Surface.openTransaction() / closeTransaction() public void setVisibility(boolean on, SurfaceControl.Transaction t) { Loading @@ -113,7 +167,7 @@ class EmulatorDisplayOverlay { return; } mVisible = on; drawIfNeeded(t); drawIfNeeded(); if (on) { t.show(mSurfaceControl); } else { Loading @@ -125,11 +179,58 @@ class EmulatorDisplayOverlay { if (mLastDW == dw && mLastDH == dh && mRotation == rotation) { return; } Slog.d(TAG, "positionSurface: dw=" + dw + ", dh=" + dh); mLastDW = dw; mLastDH = dh; mDrawNeeded = true; mRotation = rotation; drawIfNeeded(t); drawIfNeeded(); } @Override public void onDisplayAdded(int displayId) { // Do nothing } @Override public void onDisplayRemoved(int displayId) { // Do nothing } @Override public void onDisplayChanged(int displayId) { synchronized (mWmService.mGlobalLock) { if (mDisplayId != displayId) { return; } if (updateScreenBrightness(displayId)) { mDrawNeeded = true; drawIfNeeded(); } } } private boolean updateScreenBrightness(int displayId) { BrightnessInfo brightnessInfo = DisplayManagerGlobal.getInstance().getBrightnessInfo( displayId); if (brightnessInfo == null) { Slog.d(TAG, "Cannot update brightness since BrightnessInfo is null"); return false; } float adjustedBrightness = clampedBrightness( DisplayManagerGlobal.getInstance().getBrightnessInfo( displayId).adjustedBrightness); if (mScreenBrightness == adjustedBrightness) { return false; } mScreenBrightness = adjustedBrightness; return true; } private float clampedBrightness(float brightness) { if (brightness < 0.0f || brightness > 1.0f) { return FALLBACK_BRIGHTNESS; } return brightness; } } services/core/java/com/android/server/wm/WindowManagerService.java +31 −7 Original line number Diff line number Diff line Loading @@ -153,6 +153,7 @@ import static com.android.server.wm.WindowManagerInternal.WindowFocusChangeListe import static com.android.systemui.shared.Flags.enableLppAssistInvocationEffect; import static com.android.window.flags.Flags.enableDeviceStateAutoRotateSettingRefactor; import static com.android.window.flags.Flags.multiCrop; import static com.android.window.flags.Flags.screenBrightnessDimOnEmulator; import static com.android.window.flags.Flags.setScPropertiesInClient; import android.Manifest; Loading Loading @@ -4248,24 +4249,47 @@ public class WindowManagerService extends IWindowManager.Stub } } public void showEmulatorDisplayOverlayIfNeeded() { if (mContext.getResources().getBoolean( com.android.internal.R.bool.config_windowEnableCircularEmulatorDisplayOverlay) && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false) && Build.IS_EMULATOR) { @VisibleForTesting void showEmulatorDisplayOverlayIfNeeded() { if (shouldShowEmulatorDisplayOverlay()) { mH.sendMessage(mH.obtainMessage(H.SHOW_EMULATOR_DISPLAY_OVERLAY)); } } public void showEmulatorDisplayOverlay() { private boolean shouldShowEmulatorDisplayOverlay() { return enableCircularEmulatorDisplayOverlay() || enableScreenBrightnessEmulatorDisplayOverlay(); } @VisibleForTesting boolean enableCircularEmulatorDisplayOverlay() { return Build.IS_EMULATOR && mContext.getResources().getBoolean( com.android.internal.R.bool.config_windowEnableCircularEmulatorDisplayOverlay) && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false); } @VisibleForTesting boolean enableScreenBrightnessEmulatorDisplayOverlay() { return screenBrightnessDimOnEmulator() && Build.IS_EMULATOR && mContext.getResources().getBoolean( R.bool.config_windowEnableScreenBrightnessEmulatorDisplayOverlay); } @VisibleForTesting void showEmulatorDisplayOverlay() { synchronized (mGlobalLock) { if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM, ">>> showEmulatorDisplayOverlay"); if (mEmulatorDisplayOverlay == null) { mEmulatorDisplayOverlay = new EmulatorDisplayOverlay(mContext, this, getDefaultDisplayContentLocked(), mPolicy.getWindowLayerFromTypeLw(WindowManager.LayoutParams.TYPE_POINTER) * TYPE_LAYER_MULTIPLIER + 10, mTransaction); * TYPE_LAYER_MULTIPLIER + 10, mTransaction, enableCircularEmulatorDisplayOverlay(), enableScreenBrightnessEmulatorDisplayOverlay()); } mEmulatorDisplayOverlay.setVisibility(true, mTransaction); mTransaction.apply(); Loading Loading
core/java/android/window/flags/windowing_frontend.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -524,3 +524,13 @@ flag { description: "Use a single binder for task-org/transition messaging to shell" bug: "410930250" } flag { name: "screen_brightness_dim_on_emulator" namespace: "wear_systems" description: "Apply screen brightness to emulator display overlay" bug: "418830217" metadata { purpose: PURPOSE_BUGFIX } }
core/res/res/values/config.xml +3 −0 Original line number Diff line number Diff line Loading @@ -3869,6 +3869,9 @@ should show a display overlay on the screen --> <bool name="config_windowEnableCircularEmulatorDisplayOverlay">false</bool> <!-- Whether the emulator shows screen brightness dim in the overlay. --> <bool name="config_windowEnableScreenBrightnessEmulatorDisplayOverlay">false</bool> <!-- Defines the default set of global actions. Actions may still be disabled or hidden based on the current state of the device. Each item must be one of the following strings: Loading
core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -407,6 +407,7 @@ <java-symbol type="bool" name="config_windowShowCircularMask" /> <java-symbol type="bool" name="config_predictShowStartingSurface" /> <java-symbol type="bool" name="config_windowEnableCircularEmulatorDisplayOverlay" /> <java-symbol type="bool" name="config_windowEnableScreenBrightnessEmulatorDisplayOverlay" /> <java-symbol type="bool" name="config_supportMicNearUltrasound" /> <java-symbol type="bool" name="config_supportSpeakerNearUltrasound" /> <java-symbol type="bool" name="config_supportAudioSourceUnprocessed" /> Loading
services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java +114 −13 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.wm; import static android.hardware.display.DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; Loading @@ -27,16 +29,25 @@ import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.hardware.display.BrightnessInfo; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerGlobal; import android.util.Slog; import android.view.Display; import android.view.Surface; import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl; class EmulatorDisplayOverlay { import com.android.internal.annotations.VisibleForTesting; class EmulatorDisplayOverlay implements DisplayManager.DisplayListener { private static final String TAG = TAG_WITH_CLASS_NAME ? "EmulatorDisplayOverlay" : TAG_WM; private static final String TITLE = "EmulatorDisplayOverlay"; private static final float FALLBACK_BRIGHTNESS = 1.0f; private static final int MAX_OVERLAY_ALPHA = 0xFF; // Display dimensions private Point mScreenSize; Loading @@ -44,6 +55,10 @@ class EmulatorDisplayOverlay { private final Surface mSurface; private final BLASTBufferQueue mBlastBufferQueue; private final WindowManagerService mWmService; private final int mDisplayId; private final boolean mEnableScreenBrightnessDim; private int mLastDW; private int mLastDH; private boolean mDrawNeeded; Loading @@ -51,8 +66,19 @@ class EmulatorDisplayOverlay { private int mRotation; private boolean mVisible; EmulatorDisplayOverlay(Context context, DisplayContent dc, int zOrder, SurfaceControl.Transaction t) { private float mScreenBrightness; EmulatorDisplayOverlay(Context context, WindowManagerService wmService, DisplayContent dc, int zOrder, SurfaceControl.Transaction t, boolean enableCircularOverlay, boolean enableScreenBrightnessDim) { this(context, wmService, dc, zOrder, t, enableCircularOverlay, enableScreenBrightnessDim, new BLASTBufferQueue(TITLE, /* updateDestinationFrame */ true)); } @VisibleForTesting EmulatorDisplayOverlay(Context context, WindowManagerService wmService, DisplayContent dc, int zOrder, SurfaceControl.Transaction t, boolean enableCircularOverlay, boolean enableScreenBrightnessDim, BLASTBufferQueue blastBufferQueue) { final Display display = dc.getDisplay(); mScreenSize = new Point(); display.getSize(mScreenSize); Loading @@ -74,16 +100,30 @@ class EmulatorDisplayOverlay { } mSurfaceControl = ctrl; mDrawNeeded = true; mOverlay = context.getDrawable( com.android.internal.R.drawable.emulator_circular_window_overlay); mOverlay = enableCircularOverlay ? context.getDrawable( com.android.internal.R.drawable.emulator_circular_window_overlay) : null; mBlastBufferQueue = new BLASTBufferQueue(TITLE, /* updateDestinationFrame */ true); mBlastBufferQueue = blastBufferQueue; mBlastBufferQueue.update(mSurfaceControl, mScreenSize.x, mScreenSize.y, PixelFormat.RGBA_8888); mSurface = mBlastBufferQueue.createSurface(); mWmService = wmService; mDisplayId = dc.getDisplayId(); mEnableScreenBrightnessDim = enableScreenBrightnessDim; if (enableScreenBrightnessDim) { updateScreenBrightness(mDisplayId); DisplayManagerGlobal.getInstance().registerDisplayListener( this, null, INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED, context.getPackageName() ); } } private void drawIfNeeded(SurfaceControl.Transaction t) { private void drawIfNeeded() { if (!mDrawNeeded || !mVisible) { return; } Loading @@ -97,15 +137,29 @@ class EmulatorDisplayOverlay { if (c == null) { return; } c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.SRC); t.setPosition(mSurfaceControl, 0, 0); c.drawColor(getBackgroundColor(), PorterDuff.Mode.SRC); // Always draw the overlay with square dimensions int size = Math.max(mScreenSize.x, mScreenSize.y); if (mOverlay != null) { mOverlay.setBounds(0, 0, size, size); mOverlay.draw(c); } mSurface.unlockCanvasAndPost(c); } private int getBackgroundColor() { if (mEnableScreenBrightnessDim) { return getScreenBrightnessDimColor(); } else { return Color.TRANSPARENT; } } private int getScreenBrightnessDimColor() { int alpha = Math.round((1.0f - mScreenBrightness) * MAX_OVERLAY_ALPHA); return (alpha << 24) | 0x000000; } // Note: caller responsible for being inside // Surface.openTransaction() / closeTransaction() public void setVisibility(boolean on, SurfaceControl.Transaction t) { Loading @@ -113,7 +167,7 @@ class EmulatorDisplayOverlay { return; } mVisible = on; drawIfNeeded(t); drawIfNeeded(); if (on) { t.show(mSurfaceControl); } else { Loading @@ -125,11 +179,58 @@ class EmulatorDisplayOverlay { if (mLastDW == dw && mLastDH == dh && mRotation == rotation) { return; } Slog.d(TAG, "positionSurface: dw=" + dw + ", dh=" + dh); mLastDW = dw; mLastDH = dh; mDrawNeeded = true; mRotation = rotation; drawIfNeeded(t); drawIfNeeded(); } @Override public void onDisplayAdded(int displayId) { // Do nothing } @Override public void onDisplayRemoved(int displayId) { // Do nothing } @Override public void onDisplayChanged(int displayId) { synchronized (mWmService.mGlobalLock) { if (mDisplayId != displayId) { return; } if (updateScreenBrightness(displayId)) { mDrawNeeded = true; drawIfNeeded(); } } } private boolean updateScreenBrightness(int displayId) { BrightnessInfo brightnessInfo = DisplayManagerGlobal.getInstance().getBrightnessInfo( displayId); if (brightnessInfo == null) { Slog.d(TAG, "Cannot update brightness since BrightnessInfo is null"); return false; } float adjustedBrightness = clampedBrightness( DisplayManagerGlobal.getInstance().getBrightnessInfo( displayId).adjustedBrightness); if (mScreenBrightness == adjustedBrightness) { return false; } mScreenBrightness = adjustedBrightness; return true; } private float clampedBrightness(float brightness) { if (brightness < 0.0f || brightness > 1.0f) { return FALLBACK_BRIGHTNESS; } return brightness; } }
services/core/java/com/android/server/wm/WindowManagerService.java +31 −7 Original line number Diff line number Diff line Loading @@ -153,6 +153,7 @@ import static com.android.server.wm.WindowManagerInternal.WindowFocusChangeListe import static com.android.systemui.shared.Flags.enableLppAssistInvocationEffect; import static com.android.window.flags.Flags.enableDeviceStateAutoRotateSettingRefactor; import static com.android.window.flags.Flags.multiCrop; import static com.android.window.flags.Flags.screenBrightnessDimOnEmulator; import static com.android.window.flags.Flags.setScPropertiesInClient; import android.Manifest; Loading Loading @@ -4248,24 +4249,47 @@ public class WindowManagerService extends IWindowManager.Stub } } public void showEmulatorDisplayOverlayIfNeeded() { if (mContext.getResources().getBoolean( com.android.internal.R.bool.config_windowEnableCircularEmulatorDisplayOverlay) && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false) && Build.IS_EMULATOR) { @VisibleForTesting void showEmulatorDisplayOverlayIfNeeded() { if (shouldShowEmulatorDisplayOverlay()) { mH.sendMessage(mH.obtainMessage(H.SHOW_EMULATOR_DISPLAY_OVERLAY)); } } public void showEmulatorDisplayOverlay() { private boolean shouldShowEmulatorDisplayOverlay() { return enableCircularEmulatorDisplayOverlay() || enableScreenBrightnessEmulatorDisplayOverlay(); } @VisibleForTesting boolean enableCircularEmulatorDisplayOverlay() { return Build.IS_EMULATOR && mContext.getResources().getBoolean( com.android.internal.R.bool.config_windowEnableCircularEmulatorDisplayOverlay) && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false); } @VisibleForTesting boolean enableScreenBrightnessEmulatorDisplayOverlay() { return screenBrightnessDimOnEmulator() && Build.IS_EMULATOR && mContext.getResources().getBoolean( R.bool.config_windowEnableScreenBrightnessEmulatorDisplayOverlay); } @VisibleForTesting void showEmulatorDisplayOverlay() { synchronized (mGlobalLock) { if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM, ">>> showEmulatorDisplayOverlay"); if (mEmulatorDisplayOverlay == null) { mEmulatorDisplayOverlay = new EmulatorDisplayOverlay(mContext, this, getDefaultDisplayContentLocked(), mPolicy.getWindowLayerFromTypeLw(WindowManager.LayoutParams.TYPE_POINTER) * TYPE_LAYER_MULTIPLIER + 10, mTransaction); * TYPE_LAYER_MULTIPLIER + 10, mTransaction, enableCircularEmulatorDisplayOverlay(), enableScreenBrightnessEmulatorDisplayOverlay()); } mEmulatorDisplayOverlay.setVisibility(true, mTransaction); mTransaction.apply(); Loading