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

Commit 762f8151 authored by Tony Wickham's avatar Tony Wickham
Browse files

Improve Taskbar touchableRegion debuggability

- Add DebugTouchableRegion which includes the last region that we
  set as well as the reason (code path) for it, which we dump.
- If persist.debug.draw_taskbar_debug_ui is enabled, we will also
  outline the touchable region on the screen.

Flag: None
Test: testThreeButtonsTaskbarBoundsAfterConfigChangeDuringIme
Bug: 315393203

Change-Id: I70b37e8b8804c4a48ffe3956d2a24aa5eab452fd
parent 79f55365
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -169,6 +169,7 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
        mBackgroundRenderer.setBackgroundProgress(mTaskbarBackgroundProgress);
        mBackgroundRenderer.draw(canvas);
        super.dispatchDraw(canvas);
        mControllerCallbacks.drawDebugUi(canvas);
    }

    /**
+15 −0
Original line number Diff line number Diff line
@@ -19,8 +19,10 @@ import static com.android.launcher3.taskbar.TaskbarPinningController.PINNING_PER
import static com.android.launcher3.taskbar.TaskbarPinningController.PINNING_TRANSIENT;

import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.SystemProperties;
import android.view.ViewTreeObserver;

import com.android.launcher3.DeviceProfile;
@@ -39,6 +41,9 @@ import java.io.PrintWriter;
public class TaskbarDragLayerController implements TaskbarControllers.LoggableTaskbarController,
        TaskbarControllers.BackgroundRendererController {

    private static final boolean DEBUG = SystemProperties.getBoolean(
            "persist.debug.draw_taskbar_debug_ui", false);

    private final TaskbarActivityContext mActivity;
    private final TaskbarDragLayer mTaskbarDragLayer;
    private final int mFolderMargin;
@@ -299,5 +304,15 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa
                    mTaskbarStashViaTouchController,
            };
        }

        /**
         * Draws debug UI on top of everything in TaskbarDragLayer.
         */
        public void drawDebugUi(Canvas canvas) {
            if (!DEBUG) {
                return;
            }
            mControllers.taskbarInsetsController.drawDebugTouchableRegionBounds(canvas);
        }
    }
}
+43 −6
Original line number Diff line number Diff line
@@ -15,7 +15,11 @@
 */
package com.android.launcher3.taskbar

import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Insets
import android.graphics.Paint
import android.graphics.Rect
import android.graphics.Region
import android.inputmethodservice.InputMethodService.ENABLE_HIDE_IME_CAPTION_BAR
import android.os.Binder
@@ -47,6 +51,7 @@ import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarControlle
import com.android.launcher3.util.DisplayController
import java.io.PrintWriter
import kotlin.jvm.optionals.getOrNull
import kotlin.math.max

/** Handles the insets that Taskbar provides to underlying apps and the IME. */
class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTaskbarController {
@@ -58,7 +63,8 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas

    /** The bottom insets taskbar provides to the IME when IME is visible. */
    val taskbarHeightForIme: Int = context.resources.getDimensionPixelSize(R.dimen.taskbar_ime_size)
    private val touchableRegion: Region = Region()
    // The touchableRegion we will set unless some other state takes precedence.
    private val defaultTouchableRegion: Region = Region()
    private val insetsOwner: IBinder = Binder()
    private val deviceProfileChangeListener = { _: DeviceProfile ->
        onTaskbarOrBubblebarWindowHeightOrInsetsChanged()
@@ -69,6 +75,7 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas
            context,
            this::onTaskbarOrBubblebarWindowHeightOrInsetsChanged
        )
    private val debugTouchableRegion = DebugTouchableRegion()

    // Initialized in init.
    private lateinit var controllers: TaskbarControllers
@@ -124,7 +131,7 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas
            } else {
                0
            }
        val touchableHeight = Math.max(taskbarTouchableHeight, bubblesTouchableHeight)
        val touchableHeight = max(taskbarTouchableHeight, bubblesTouchableHeight)

        if (
            controllers.bubbleControllers.isPresent &&
@@ -132,14 +139,14 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas
        ) {
            val iconBounds =
                controllers.bubbleControllers.get().bubbleBarViewController.bubbleBarBounds
            touchableRegion.set(
            defaultTouchableRegion.set(
                iconBounds.left,
                iconBounds.top,
                iconBounds.right,
                iconBounds.bottom
            )
        } else {
            touchableRegion.set(
            defaultTouchableRegion.set(
                0,
                windowLayoutParams.height - touchableHeight,
                context.deviceProfile.widthPx,
@@ -296,6 +303,8 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas
            context.dragLayer,
            insetsInfo.touchableRegion
        )
        debugTouchableRegion.lastSetTouchableBounds.set(insetsInfo.touchableRegion.bounds)

        val bubbleBarVisible =
            controllers.bubbleControllers.isPresent &&
                controllers.bubbleControllers.get().bubbleBarViewController.isBubbleBarVisible()
@@ -303,21 +312,28 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas
        if (context.dragLayer.alpha < AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD) {
            // Let touches pass through us.
            insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION)
            debugTouchableRegion.lastSetTouchableReason = "Taskbar is invisible"
        } else if (
            controllers.navbarButtonsViewController.isImeVisible &&
                controllers.taskbarStashController.isStashed
        ) {
            // Let touches pass through us.
            insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION)
            debugTouchableRegion.lastSetTouchableReason = "Stashed over IME"
        } else if (!controllers.uiController.isTaskbarTouchable) {
            // Let touches pass through us.
            insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION)
            debugTouchableRegion.lastSetTouchableReason = "Taskbar is not touchable"
        } else if (controllers.taskbarDragController.isSystemDragInProgress) {
            // Let touches pass through us.
            insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION)
            debugTouchableRegion.lastSetTouchableReason = "System drag is in progress"
        } else if (context.isTaskbarWindowFullscreen) {
            // Intercept entire fullscreen window.
            insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_FRAME)
            insetsIsTouchableRegion = false
            debugTouchableRegion.lastSetTouchableReason = "Taskbar is fullscreen"
            context.dragLayer.getBoundsInWindow(debugTouchableRegion.lastSetTouchableBounds, false)
        } else if (
            controllers.taskbarViewController.areIconsVisible() ||
                context.isNavBarKidsModeActive ||
@@ -346,19 +362,33 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas
                    region.op(bubbleBarBounds, Region.Op.UNION)
                }
                insetsInfo.touchableRegion.set(region)
                debugTouchableRegion.lastSetTouchableReason = "Transient Taskbar is in Overview"
                debugTouchableRegion.lastSetTouchableBounds.set(region.bounds)
            } else {
                insetsInfo.touchableRegion.set(touchableRegion)
                insetsInfo.touchableRegion.set(defaultTouchableRegion)
                debugTouchableRegion.lastSetTouchableReason = "Using default touchable region"
                debugTouchableRegion.lastSetTouchableBounds.set(defaultTouchableRegion.bounds)
            }
            insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION)
            insetsIsTouchableRegion = false
        } else {
            insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION)
            debugTouchableRegion.lastSetTouchableReason =
                "Icons are not visible, but other components such as 3 buttons might be"
        }
        context.excludeFromMagnificationRegion(insetsIsTouchableRegion)
    }

    /** Draws the last set touchableRegion as a red rectangle onto the given Canvas. */
    fun drawDebugTouchableRegionBounds(canvas: Canvas) {
        val paint = Paint()
        paint.color = Color.RED
        paint.style = Paint.Style.STROKE
        canvas.drawRect(debugTouchableRegion.lastSetTouchableBounds, paint)
    }

    override fun dumpLogs(prefix: String, pw: PrintWriter) {
        pw.println(prefix + "TaskbarInsetsController:")
        pw.println("${prefix}TaskbarInsetsController:")
        pw.println("$prefix\twindowHeight=${windowLayoutParams.height}")
        for (provider in windowLayoutParams.providedInsets) {
            pw.print(
@@ -377,5 +407,12 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas
            }
            pw.println()
        }
        pw.println("$prefix\tlastSetTouchableBounds=${debugTouchableRegion.lastSetTouchableBounds}")
        pw.println("$prefix\tlastSetTouchableReason=${debugTouchableRegion.lastSetTouchableReason}")
    }

    class DebugTouchableRegion {
        val lastSetTouchableBounds = Rect()
        var lastSetTouchableReason = ""
    }
}
+31 −0
Original line number Diff line number Diff line
@@ -17,16 +17,23 @@ package com.android.quickstep;

import static com.android.quickstep.TaskbarModeSwitchRule.Mode.PERSISTENT;

import android.graphics.Rect;

import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;

import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.Closeable;
import java.io.IOException;

@LargeTest
@RunWith(AndroidJUnit4.class)
public class TaplTestsPersistentTaskbar extends AbstractTaplTestsTaskbar {
@@ -39,4 +46,28 @@ public class TaplTestsPersistentTaskbar extends AbstractTaplTestsTaskbar {
        // Width check is performed inside TAPL whenever getTaskbar() is called.
        getTaskbar();
    }

    @Test
    @NavigationModeSwitch(mode = NavigationModeSwitchRule.Mode.THREE_BUTTON)
    public void testThreeButtonsTaskbarBoundsAfterConfigChangeDuringIme() {
        // Start off in light mode.
        try (Closeable c = InstrumentationRegistry.getInstrumentation().getUiAutomation()
                .executeShellCommand("cmd uimode night no")) {
            Rect taskbarBoundsBefore = getTaskbar().getVisibleBounds();
            startImeTestActivity();
            // IME should stash the taskbar, which hides icons even in 3 button mode.
            mLauncher.getLaunchedAppState().assertTaskbarHidden();
            // Switch to dark mode (any configuration change here would do).
            InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand(
                    "cmd uimode night yes").close();
            // Close IME to check new taskbar bounds.
            mLauncher.pressBack();
            Rect taskbarBoundsAfter = getTaskbar().getVisibleBounds();
            Assert.assertEquals(
                    "Taskbar bounds are not the same after a configuration change while stashed.",
                    taskbarBoundsBefore, taskbarBoundsAfter);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -153,7 +153,7 @@ public final class Taskbar {
        return By.clazz(TextView.class).text("");
    }

    private Rect getVisibleBounds() {
    public Rect getVisibleBounds() {
        return mLauncher.waitForSystemLauncherObject(TASKBAR_RES_ID).getVisibleBounds();
    }