diff options
| author | 2023-12-11 11:46:08 +0000 | |
|---|---|---|
| committer | 2023-12-11 11:46:08 +0000 | |
| commit | 279357e3848275d4f13cfefbeeef9f39ebd93847 (patch) | |
| tree | 71513dee8815cb913279b3b74b409998c09e692d | |
| parent | c7cb41b193db64745114998646b0db240b07a512 (diff) | |
| parent | 8d6a7750d9c2cf4623d0822794533bafb7a2ce17 (diff) | |
Merge "[Status Bar] Bottom margin command" into main
3 files changed, 135 insertions, 7 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/StatusBarInsetsCommand.kt b/packages/SystemUI/src/com/android/systemui/StatusBarInsetsCommand.kt new file mode 100644 index 000000000000..7e2a1e1e5618 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/StatusBarInsetsCommand.kt @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui + +import android.view.Surface +import android.view.Surface.Rotation +import com.android.systemui.statusbar.commandline.ParseableCommand +import com.android.systemui.statusbar.commandline.Type +import java.io.PrintWriter + +class StatusBarInsetsCommand( + private val callback: Callback, +) : ParseableCommand(NAME) { + + val bottomMargin: BottomMarginCommand? by subCommand(BottomMarginCommand()) + + override fun execute(pw: PrintWriter) { + callback.onExecute(command = this, pw) + } + + interface Callback { + fun onExecute(command: StatusBarInsetsCommand, printWriter: PrintWriter) + } + + companion object { + const val NAME = "status-bar-insets" + } +} + +class BottomMarginCommand : ParseableCommand(NAME) { + + private val rotationDegrees: Int? by + param( + longName = "rotation", + shortName = "r", + description = "For which rotation the margin should be set. One of 0, 90, 180, 270", + valueParser = Type.Int, + ) + + @Rotation + val rotationValue: Int? + get() = ROTATION_DEGREES_TO_VALUE_MAPPING[rotationDegrees] + + val marginBottomDp: Float? by + param( + longName = "margin", + shortName = "m", + description = "Margin amount, in dp. Can be a fractional value, such as 10.5", + valueParser = Type.Float, + ) + + override fun execute(pw: PrintWriter) { + // Not needed for a subcommand + } + + companion object { + const val NAME = "bottom-margin" + private val ROTATION_DEGREES_TO_VALUE_MAPPING = + mapOf( + 0 to Surface.ROTATION_0, + 90 to Surface.ROTATION_90, + 180 to Surface.ROTATION_180, + 270 to Surface.ROTATION_270, + ) + + val ROTATION_DEGREES_OPTIONS: Set<Int> = ROTATION_DEGREES_TO_VALUE_MAPPING.keys + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt index 3b96f5793fe8..877bd7c11e95 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt @@ -42,6 +42,9 @@ import com.android.systemui.util.leak.RotationUtils.Rotation import com.android.systemui.util.leak.RotationUtils.getExactRotation import com.android.systemui.util.leak.RotationUtils.getResourcesForRotation import com.android.app.tracing.traceSection +import com.android.systemui.BottomMarginCommand +import com.android.systemui.StatusBarInsetsCommand +import com.android.systemui.statusbar.commandline.CommandRegistry import java.io.PrintWriter import java.lang.Math.max import javax.inject.Inject @@ -64,7 +67,8 @@ import javax.inject.Inject class StatusBarContentInsetsProvider @Inject constructor( val context: Context, val configurationController: ConfigurationController, - val dumpManager: DumpManager + val dumpManager: DumpManager, + val commandRegistry: CommandRegistry, ) : CallbackController<StatusBarContentInsetsChangedListener>, ConfigurationController.ConfigurationListener, Dumpable { @@ -80,6 +84,13 @@ class StatusBarContentInsetsProvider @Inject constructor( init { configurationController.addCallback(this) dumpManager.registerDumpable(TAG, this) + commandRegistry.registerCommand(StatusBarInsetsCommand.NAME) { + StatusBarInsetsCommand(object : StatusBarInsetsCommand.Callback { + override fun onExecute(command: StatusBarInsetsCommand, printWriter: PrintWriter) { + executeCommand(command, printWriter) + } + }) + } } override fun addCallback(listener: StatusBarContentInsetsChangedListener) { @@ -271,8 +282,41 @@ class StatusBarContentInsetsProvider @Inject constructor( statusBarContentHeight) } + private fun executeCommand(command: StatusBarInsetsCommand, printWriter: PrintWriter) { + command.bottomMargin?.let { executeBottomMarginCommand(it, printWriter) } + } + + private fun executeBottomMarginCommand(command: BottomMarginCommand, printWriter: PrintWriter) { + val rotation = command.rotationValue + if (rotation == null) { + printWriter.println( + "Rotation should be one of ${BottomMarginCommand.ROTATION_DEGREES_OPTIONS}" + ) + return + } + val marginBottomDp = command.marginBottomDp + if (marginBottomDp == null) { + printWriter.println("Margin bottom not set.") + return + } + setBottomMarginOverride(rotation, marginBottomDp) + } + + private val marginBottomOverrides = mutableMapOf<Int, Int>() + + private fun setBottomMarginOverride(rotation: Int, marginBottomDp: Float) { + insetsCache.evictAll() + val marginBottomPx = (marginBottomDp * context.resources.displayMetrics.density).toInt() + marginBottomOverrides[rotation] = marginBottomPx + notifyInsetsChanged() + } + @Px private fun getBottomAlignedMargin(targetRotation: Int, resources: Resources): Int { + val override = marginBottomOverrides[targetRotation] + if (override != null) { + return override + } val dimenRes = when (targetRotation) { Surface.ROTATION_0 -> R.dimen.status_bar_bottom_aligned_margin_rotation_0 @@ -294,6 +338,7 @@ class StatusBarContentInsetsProvider @Inject constructor( pw.println("$key -> $rect") } pw.println(insetsCache) + pw.println("Bottom margin overrides: $marginBottomOverrides") } private fun getCacheKey( diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt index 5c5624692f07..84b2c4bfed34 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt @@ -24,6 +24,7 @@ import android.view.DisplayCutout import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager +import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.leak.RotationUtils import com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE @@ -31,6 +32,7 @@ import com.android.systemui.util.leak.RotationUtils.ROTATION_NONE import com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE import com.android.systemui.util.leak.RotationUtils.ROTATION_UPSIDE_DOWN import com.android.systemui.util.leak.RotationUtils.Rotation +import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import junit.framework.Assert.assertTrue @@ -39,7 +41,6 @@ import org.junit.Test import org.mockito.ArgumentMatchers.any import org.mockito.Mock import org.mockito.Mockito.`when` -import org.mockito.Mockito.mock import org.mockito.MockitoAnnotations @SmallTest @@ -556,7 +557,7 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { fun testDisplayChanged_returnsUpdatedInsets() { // GIVEN: get insets on the first display and switch to the second display val provider = StatusBarContentInsetsProvider(contextMock, configurationController, - mock(DumpManager::class.java)) + mock<DumpManager>(), mock<CommandRegistry>()) configuration.windowConfiguration.setMaxBounds(Rect(0, 0, 1080, 2160)) val firstDisplayInsets = provider.getStatusBarContentAreaForRotation(ROTATION_NONE) @@ -575,7 +576,7 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { // GIVEN: get insets on the first display, switch to the second display, // get insets and switch back val provider = StatusBarContentInsetsProvider(contextMock, configurationController, - mock(DumpManager::class.java)) + mock<DumpManager>(), mock<CommandRegistry>()) configuration.windowConfiguration.setMaxBounds(Rect(0, 0, 1080, 2160)) val firstDisplayInsetsFirstCall = provider @@ -601,7 +602,7 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { configuration.windowConfiguration.setMaxBounds(0, 0, 100, 100) configurationController.onConfigurationChanged(configuration) val provider = StatusBarContentInsetsProvider(contextMock, configurationController, - mock(DumpManager::class.java)) + mock<DumpManager>(), mock<CommandRegistry>()) val listener = object : StatusBarContentInsetsChangedListener { var triggered = false @@ -623,7 +624,7 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { fun onDensityOrFontScaleChanged_listenerNotified() { configuration.densityDpi = 12 val provider = StatusBarContentInsetsProvider(contextMock, configurationController, - mock(DumpManager::class.java)) + mock<DumpManager>(), mock<CommandRegistry>()) val listener = object : StatusBarContentInsetsChangedListener { var triggered = false @@ -644,7 +645,7 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { @Test fun onThemeChanged_listenerNotified() { val provider = StatusBarContentInsetsProvider(contextMock, configurationController, - mock(DumpManager::class.java)) + mock<DumpManager>(), mock<CommandRegistry>()) val listener = object : StatusBarContentInsetsChangedListener { var triggered = false |