[Decor] Make ScreenDecorations.mDebug non-final

Most of the code behind DEBUG was logging-related. This CL converts most
logs to use the LogBuffer implementation, but keeps a few `onPreDraw`
logs behind a new `DEBUG_LOGGING` flag, which is still statically
defined.

This CL also moves `DEBUG` to a new `mDebug` field, which is private and
modifiable at runtime. The `setDebug` method is unused in this CL, but
will be supported in follow-up. Setting debug is still supported through
the old sysprop `debug.screenshot_rounded_corners`. In the future,
setting debug will be supported over the command line, and will
essentially re-setup the screen decor wih the flag enabled.

Test: adb shell setprop debug.screenshot_rounded_corners 1 && restart-sysui
Test: ScreenDecorationsTest
Bug: 285941724
Change-Id: Ibc19ae82257d8e5fa4c45582d7d83067bbf67548
This commit is contained in:
Evan Laird
2023-06-07 11:58:10 -04:00
parent 68270b2198
commit 76a732f8e5
4 changed files with 122 additions and 35 deletions

View File

@@ -49,8 +49,11 @@ import kotlin.math.floor
* When the HWC of the device supports Composition.DISPLAY_DECORATION, we use this layer to draw
* screen decorations.
*/
class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDecorationSupport) :
DisplayCutoutBaseView(context) {
class ScreenDecorHwcLayer(
context: Context,
displayDecorationSupport: DisplayDecorationSupport,
private val debug: Boolean,
) : DisplayCutoutBaseView(context) {
val colorMode: Int
private val useInvertedAlphaColor: Boolean
private val color: Int
@@ -74,7 +77,7 @@ class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDec
throw IllegalArgumentException("Attempting to use unsupported mode " +
"${PixelFormat.formatToString(displayDecorationSupport.format)}")
}
if (DEBUG_COLOR) {
if (debug) {
color = Color.GREEN
bgColor = Color.TRANSPARENT
colorMode = ActivityInfo.COLOR_MODE_DEFAULT
@@ -106,7 +109,7 @@ class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDec
override fun onAttachedToWindow() {
super.onAttachedToWindow()
parent.requestTransparentRegion(this)
if (!DEBUG_COLOR) {
if (!debug) {
viewRootImpl.setDisplayDecoration(true)
}
@@ -143,12 +146,12 @@ class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDec
override fun gatherTransparentRegion(region: Region?): Boolean {
region?.let {
calculateTransparentRect()
if (DEBUG_COLOR) {
if (debug) {
// Since we're going to draw a rectangle where the layer would
// normally be transparent, treat the transparent region as
// empty. We still want this method to be called, though, so
// that it calculates the transparent rect at the right time
// to match !DEBUG_COLOR.
// to match ![debug]
region.setEmpty()
} else {
region.op(transparentRect, Region.Op.INTERSECT)
@@ -421,8 +424,4 @@ class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDec
ipw.println("roundedCornerBottomSize=$roundedCornerBottomSize")
ipw.decreaseIndent()
}
companion object {
private val DEBUG_COLOR = ScreenDecorations.DEBUG_COLOR
}
}

View File

@@ -104,7 +104,7 @@ import javax.inject.Inject;
*/
@SysUISingleton
public class ScreenDecorations implements CoreStartable, Dumpable {
private static final boolean DEBUG = false;
private static final boolean DEBUG_LOGGING = false;
private static final String TAG = "ScreenDecorations";
// Provide a way for factory to disable ScreenDecorations to run the Display tests.
@@ -112,7 +112,8 @@ public class ScreenDecorations implements CoreStartable, Dumpable {
SystemProperties.getBoolean("debug.disable_screen_decorations", false);
private static final boolean DEBUG_SCREENSHOT_ROUNDED_CORNERS =
SystemProperties.getBoolean("debug.screenshot_rounded_corners", false);
static final boolean DEBUG_COLOR = DEBUG_SCREENSHOT_ROUNDED_CORNERS;
private boolean mDebug = DEBUG_SCREENSHOT_ROUNDED_CORNERS;
private int mDebugColor = Color.RED;
private static final int[] DISPLAY_CUTOUT_IDS = {
R.id.display_cutout,
@@ -357,6 +358,26 @@ public class ScreenDecorations implements CoreStartable, Dumpable {
mAuthController.addCallback(mAuthControllerCallback);
}
/**
* Change the value of {@link ScreenDecorations#mDebug}. This operation is heavyweight, since
* it requires essentially re-init-ing this screen decorations process with the debug
* information taken into account.
*/
private void setDebug(boolean debug) {
if (mDebug == debug) {
return;
}
mExecutor.execute(() -> {
// Re-trigger all of the screen decorations setup here so that the debug values
// can be picked up
removeAllOverlays();
removeHwcOverlay();
startOnScreenDecorationsThread();
updateColorInversionDefault();
});
}
private boolean isPrivacyDotEnabled() {
return mDotFactory.getHasProviders();
}
@@ -436,15 +457,12 @@ public class ScreenDecorations implements CoreStartable, Dumpable {
// - we are trying to redraw. This because WM resized our window and told us to.
// - the config change has been dispatched, so WM is no longer deferring layout.
mPendingConfigChange = true;
if (DEBUG) {
if (mRotation != newRotation) {
Log.i(TAG, "Rotation changed, deferring " + newRotation
+ ", staying at " + mRotation);
}
if (displayModeChanged(mDisplayMode, newDisplayMode)) {
Log.i(TAG, "Resolution changed, deferring " + newDisplayMode
+ ", staying at " + mDisplayMode);
}
if (mRotation != newRotation) {
mLogger.logRotationChangeDeferred(mRotation, newRotation);
}
if (displayModeChanged(mDisplayMode, newDisplayMode)) {
mLogger.logDisplayModeChanged(
newDisplayMode.getModeId(), mDisplayMode.getModeId());
}
if (mOverlays != null) {
@@ -757,7 +775,8 @@ public class ScreenDecorations implements CoreStartable, Dumpable {
}
mScreenDecorHwcWindow = (ViewGroup) LayoutInflater.from(mContext).inflate(
R.layout.screen_decor_hwc_layer, null);
mScreenDecorHwcLayer = new ScreenDecorHwcLayer(mContext, mHwcScreenDecorationSupport);
mScreenDecorHwcLayer =
new ScreenDecorHwcLayer(mContext, mHwcScreenDecorationSupport, mDebug);
mScreenDecorHwcWindow.addView(mScreenDecorHwcLayer, new FrameLayout.LayoutParams(
MATCH_PARENT, MATCH_PARENT, Gravity.TOP | Gravity.START));
mWindowManager.addView(mScreenDecorHwcWindow, getHwcWindowLayoutParams());
@@ -805,7 +824,7 @@ public class ScreenDecorations implements CoreStartable, Dumpable {
lp.height = MATCH_PARENT;
lp.setTitle("ScreenDecorHwcOverlay");
lp.gravity = Gravity.TOP | Gravity.START;
if (!DEBUG_COLOR) {
if (!mDebug) {
lp.setColorMode(ActivityInfo.COLOR_MODE_A8);
}
return lp;
@@ -913,19 +932,40 @@ public class ScreenDecorations implements CoreStartable, Dumpable {
new UserTracker.Callback() {
@Override
public void onUserChanged(int newUser, @NonNull Context userContext) {
if (DEBUG) {
Log.d(TAG, "UserSwitched newUserId=" + newUser);
}
mLogger.logUserSwitched(newUser);
// update color inversion setting to the new user
mColorInversionSetting.setUserId(newUser);
updateColorInversion(mColorInversionSetting.getValue());
}
};
/**
* Use the current value of {@link ScreenDecorations#mColorInversionSetting} and passes it
* to {@link ScreenDecorations#updateColorInversion}
*/
private void updateColorInversionDefault() {
int inversion = 0;
if (mColorInversionSetting != null) {
inversion = mColorInversionSetting.getValue();
}
updateColorInversion(inversion);
}
/**
* Update the tint color of screen decoration assets. Defaults to Color.BLACK. In the case of
* a color inversion being set, use Color.WHITE (which inverts to black).
*
* When {@link ScreenDecorations#mDebug} is {@code true}, this value is updated to use
* {@link ScreenDecorations#mDebugColor}, and does not handle inversion.
*
* @param colorsInvertedValue if non-zero, assume that colors are inverted, and use Color.WHITE
* for screen decoration tint
*/
private void updateColorInversion(int colorsInvertedValue) {
mTintColor = colorsInvertedValue != 0 ? Color.WHITE : Color.BLACK;
if (DEBUG_COLOR) {
mTintColor = Color.RED;
if (mDebug) {
mTintColor = mDebugColor;
}
updateOverlayProviderViews(new Integer[] {
@@ -966,7 +1006,9 @@ public class ScreenDecorations implements CoreStartable, Dumpable {
int oldRotation = mRotation;
mPendingConfigChange = false;
updateConfiguration();
if (DEBUG) Log.i(TAG, "onConfigChanged from rot " + oldRotation + " to " + mRotation);
if (oldRotation != mRotation) {
mLogger.logRotationChanged(oldRotation, mRotation);
}
setupDecorations();
if (mOverlays != null) {
// Updating the layout params ensures that ViewRootImpl will call relayoutWindow(),
@@ -1199,7 +1241,7 @@ public class ScreenDecorations implements CoreStartable, Dumpable {
paint.setColor(mColor);
paint.setStyle(Paint.Style.FILL);
if (DEBUG) {
if (DEBUG_LOGGING) {
getViewTreeObserver().addOnDrawListener(() -> Log.i(TAG,
getWindowTitleByPos(pos) + " drawn in rot " + mRotation));
}
@@ -1392,7 +1434,7 @@ public class ScreenDecorations implements CoreStartable, Dumpable {
mView.getViewTreeObserver().removeOnPreDrawListener(this);
if (mTargetRotation == mRotation
&& !displayModeChanged(mDisplayMode, mTargetDisplayMode)) {
if (DEBUG) {
if (DEBUG_LOGGING) {
final String title = mPosition < 0 ? "ScreenDecorHwcLayer"
: getWindowTitleByPos(mPosition);
Log.i(TAG, title + " already in target rot "
@@ -1408,7 +1450,7 @@ public class ScreenDecorations implements CoreStartable, Dumpable {
// This changes the window attributes - we need to restart the traversal for them to
// take effect.
updateConfiguration();
if (DEBUG) {
if (DEBUG_LOGGING) {
final String title = mPosition < 0 ? "ScreenDecorHwcLayer"
: getWindowTitleByPos(mPosition);
Log.i(TAG, title
@@ -1443,7 +1485,7 @@ public class ScreenDecorations implements CoreStartable, Dumpable {
final Display.Mode displayMode = mDisplayInfo.getMode();
if ((displayRotation != mRotation || displayModeChanged(mDisplayMode, displayMode))
&& !mPendingConfigChange) {
if (DEBUG) {
if (DEBUG_LOGGING) {
if (displayRotation != mRotation) {
Log.i(TAG, "Drawing rot " + mRotation + ", but display is at rot "
+ displayRotation + ". Restarting draw");

View File

@@ -21,9 +21,9 @@ import android.graphics.Rect
import android.graphics.RectF
import androidx.core.graphics.toRectF
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogLevel.DEBUG
import com.android.systemui.log.LogLevel.ERROR
import com.android.systemui.log.LogLevel.INFO
import com.android.systemui.log.dagger.ScreenDecorationsLog
import com.google.errorprone.annotations.CompileTimeConstant
import javax.inject.Inject
@@ -164,4 +164,49 @@ constructor(
fun cameraProtectionEvent(@CompileTimeConstant cameraProtectionEvent: String) {
logBuffer.log(TAG, DEBUG, cameraProtectionEvent)
}
fun logRotationChangeDeferred(currentRot: Int, newRot: Int) {
logBuffer.log(
TAG,
INFO,
{
int1 = currentRot
int2 = newRot
},
{ "Rotation changed, deferring $int2, staying at $int2" },
)
}
fun logRotationChanged(oldRot: Int, newRot: Int) {
logBuffer.log(
TAG,
INFO,
{
int1 = oldRot
int2 = newRot
},
{ "Rotation changed from $int1 to $int2" }
)
}
fun logDisplayModeChanged(currentMode: Int, newMode: Int) {
logBuffer.log(
TAG,
INFO,
{
int1 = currentMode
int2 = newMode
},
{ "Resolution changed, deferring mode change to $int2, staying at $int1" },
)
}
fun logUserSwitched(newUser: Int) {
logBuffer.log(
TAG,
DEBUG,
{ int1 = newUser },
{ "UserSwitched newUserId=$int1. Updating color inversion setting" },
)
}
}

View File

@@ -74,7 +74,8 @@ class ScreenDecorHwcLayerTest : SysuiTestCase() {
val decorationSupport = DisplayDecorationSupport()
decorationSupport.format = PixelFormat.R_8
decorHwcLayer = Mockito.spy(ScreenDecorHwcLayer(mContext, decorationSupport))
decorHwcLayer =
Mockito.spy(ScreenDecorHwcLayer(mContext, decorationSupport, /* debug */ false))
whenever(decorHwcLayer.width).thenReturn(displayWidth)
whenever(decorHwcLayer.height).thenReturn(displayHeight)
whenever(decorHwcLayer.context).thenReturn(mockContext)