From bb3af5d904586d8f3165cc10e52e7e445e19ea46 Mon Sep 17 00:00:00 2001 From: Saumya Prakash Date: Fri, 9 Feb 2024 20:10:07 +0000 Subject: [PATCH] Add insets for taskbar when a camera cutout interrupts it Certain devices have camera cutouts that taskbar's insets did not account for previously. This change adds in the cutout's height as a bottom inset (if it is present) to avoid a black bar being drawn in the taskbar area. Fix: 322954760 Test: Open a full screen app on a large screen device and ensure that a black bar doesn't show up when rotating the screen to 90 degrees and 180 degrees. Flag: N/A Change-Id: I876274b561c7f0101554654ce758fc9c08180de7 --- .../taskbar/TaskbarInsetsController.kt | 53 ++++++++++++++----- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt index b8e6889a5b..aa457ca4f1 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt @@ -24,11 +24,13 @@ import android.graphics.Region import android.inputmethodservice.InputMethodService.ENABLE_HIDE_IME_CAPTION_BAR import android.os.Binder import android.os.IBinder +import android.view.DisplayInfo import android.view.Gravity import android.view.InsetsFrameProvider import android.view.InsetsFrameProvider.SOURCE_DISPLAY import android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER import android.view.InsetsSource.FLAG_SUPPRESS_SCRIM +import android.view.Surface import android.view.ViewTreeObserver import android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME import android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION @@ -155,19 +157,20 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas } val gravity = windowLayoutParams.gravity - for (provider in windowLayoutParams.providedInsets) { - setProviderInsets(provider, gravity) - } - if (windowLayoutParams.paramsForRotation != null) { + // Pre-calculate insets for different providers across different rotations for this gravity + for (rotation in Surface.ROTATION_0..Surface.ROTATION_270) { // Add insets for navbar rotated params - for (layoutParams in windowLayoutParams.paramsForRotation) { + if (windowLayoutParams.paramsForRotation != null) { + val layoutParams = windowLayoutParams.paramsForRotation[rotation] for (provider in layoutParams.providedInsets) { - setProviderInsets(provider, layoutParams.gravity) + setProviderInsets(provider, layoutParams.gravity, rotation) } } + for (provider in windowLayoutParams.providedInsets) { + setProviderInsets(provider, gravity, rotation) + } } - context.notifyUpdateLayoutParams() } @@ -211,12 +214,12 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas ) } - private fun setProviderInsets(provider: InsetsFrameProvider, gravity: Int) { + private fun setProviderInsets(provider: InsetsFrameProvider, gravity: Int, endRotation: Int) { val contentHeight = controllers.taskbarStashController.contentHeightToReportToApps val tappableHeight = controllers.taskbarStashController.tappableHeightToReportToApps val res = context.resources if (provider.type == navigationBars() || provider.type == mandatorySystemGestures()) { - provider.insetsSize = getInsetsForGravity(contentHeight, gravity) + provider.insetsSize = getInsetsForGravityWithCutout(contentHeight, gravity, endRotation) } else if (provider.type == tappableElement()) { provider.insetsSize = getInsetsForGravity(tappableHeight, gravity) } else if (provider.type == systemGestures() && provider.index == INDEX_LEFT) { @@ -274,6 +277,30 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas } } + /** + * Calculate the [Insets] for taskbar after a rotation, specifically for any potential cutouts + * in the screen that can come from the camera. + */ + private fun getInsetsForGravityWithCutout(inset: Int, gravity: Int, rot: Int): Insets { + val display = context.display + // If there is no cutout, fall back to the original method of calculating insets + val cutout = display.cutout ?: return getInsetsForGravity(inset, gravity) + val rotation = display.rotation + val info = DisplayInfo() + display.getDisplayInfo(info) + val rotatedCutout = cutout.getRotated(info.logicalWidth, info.logicalHeight, rotation, rot) + + if ((gravity and Gravity.BOTTOM) == Gravity.BOTTOM) { + return Insets.of(0, 0, 0, maxOf(inset, rotatedCutout.safeInsetBottom)) + } + + // TODO(b/230394142): seascape + val isSeascape = (gravity and Gravity.START) == Gravity.START + val leftInset = if (isSeascape) maxOf(inset, rotatedCutout.safeInsetLeft) else 0 + val rightInset = if (isSeascape) 0 else maxOf(inset, rotatedCutout.safeInsetRight) + return Insets.of(leftInset, 0, rightInset, 0) + } + /** * @return [Insets] where the [inset] is either used as a bottom inset or right/left inset if * using 3 button nav @@ -309,9 +336,11 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas controllers.bubbleControllers.isPresent && controllers.bubbleControllers.get().bubbleBarViewController.isBubbleBarVisible() var insetsIsTouchableRegion = true - if (context.isPhoneButtonNavMode && - (!controllers.navbarButtonsViewController.isImeVisible - || !controllers.navbarButtonsViewController.isImeRenderingNavButtons)) { + if ( + context.isPhoneButtonNavMode && + (!controllers.navbarButtonsViewController.isImeVisible || + !controllers.navbarButtonsViewController.isImeRenderingNavButtons) + ) { insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_FRAME) insetsIsTouchableRegion = false } else if (context.dragLayer.alpha < AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD) {