Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 76a732f8 authored by Evan Laird's avatar Evan Laird
Browse files

[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
parent 68270b21
Loading
Loading
Loading
Loading
+9 −10
Original line number Diff line number Diff line
@@ -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
    }
}
+65 −23
Original line number Diff line number Diff line
@@ -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);
                        mLogger.logRotationChangeDeferred(mRotation, newRotation);
                    }
                    if (displayModeChanged(mDisplayMode, newDisplayMode)) {
                            Log.i(TAG, "Resolution changed, deferring " + newDisplayMode
                                    + ", staying at " + mDisplayMode);
                        }
                        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");
+46 −1
Original line number Diff line number Diff line
@@ -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" },
        )
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -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)