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

Commit dc566559 authored by Tony Wickham's avatar Tony Wickham Committed by Android (Google) Code Review
Browse files

Merge "Improve Taskbar touchableRegion debuggability" into main

parents a15b88f4 762f8151
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();
    }