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

Commit 2752ad14 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Implement the rounded horn in the UnderlayContainer." into main

parents 176250ce 86cd9e72
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.systemui.underlay.ui.compose

import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import javax.inject.Inject
@@ -27,6 +26,5 @@ interface UnderlayComposableProvider {

class UnderlayComposableProviderImpl @Inject constructor() : UnderlayComposableProvider {

  @Composable
  override fun Content(modifier: Modifier) { }
    @Composable override fun Content(modifier: Modifier) {}
}
+57 −6
Original line number Diff line number Diff line
@@ -16,25 +16,75 @@

package com.android.systemui.underlay.ui.compose

import android.graphics.Rect
import android.util.Log
import android.view.ViewTreeObserver
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.mandatorySystemGestures
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.android.compose.PlatformIconButton
import com.android.systemui.res.R
import com.android.systemui.underlay.ui.shape.TopConcaveArcShape

@Composable
fun UnderlayContainer(
    modifier: Modifier = Modifier,
    content: UnderlayComposableProvider,
) {
    Box(modifier = modifier) {
        // TODO: b/407634988 - Add rounded horns
fun UnderlayContainer(modifier: Modifier = Modifier, content: UnderlayComposableProvider) {
    val density = LocalDensity.current
    val hornRadiusPx = with(density) { HornRadius.toPx() }

    val view = LocalView.current
    var touchableRect: Rect by remember { mutableStateOf((Rect())) }

    DisposableEffect(view, touchableRect) {
        val listener =
            ViewTreeObserver.OnComputeInternalInsetsListener { inoutInfo ->
                inoutInfo.setTouchableInsets(
                    ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION
                )
                inoutInfo.touchableRegion.set(touchableRect)
            }

        view.viewTreeObserver.addOnComputeInternalInsetsListener(listener)

        onDispose { view.viewTreeObserver.removeOnComputeInternalInsetsListener(listener) }
    }

    val underlayShape = remember(HornRadius) { TopConcaveArcShape(HornRadius) }

    val mandatorySystemGesturesBottomPadding =
        WindowInsets.mandatorySystemGestures.asPaddingValues().calculateBottomPadding()

    Box(
        modifier =
            modifier
                .onGloballyPositioned { layoutCoordinates ->
                    val heightPx = layoutCoordinates.size.height
                    val widthPx = layoutCoordinates.size.width
                    val hornHeightPx = hornRadiusPx.toInt()
                    touchableRect = Rect(0, hornHeightPx, widthPx, heightPx)
                }
                .background(color = MaterialTheme.colorScheme.inverseSurface, shape = underlayShape)
                .clip(underlayShape)
                // Offset above gesture region and below horns
                .padding(top = HornRadius, bottom = mandatorySystemGesturesBottomPadding)
    ) {
        content.Content(modifier = Modifier)

        // Close Button.
@@ -52,3 +102,4 @@ fun UnderlayContainer(
}

private const val TAG = "UnderlayContainer"
private val HornRadius = 28.dp
+65 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.underlay.data.repository

import android.content.Intent
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.broadcastDispatcher
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runCurrent
import com.android.systemui.kosmos.runTest
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runCurrent
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
@SmallTest
class UnderlayRepositoryTest : SysuiTestCase() {
    private val kosmos = testKosmos()

    @Test
    fun isUnderlayAttached_whenCreated_true() =
        kosmos.runTest {
            val isUnderlayAttached by collectLastValue(underlayRepository.isUnderlayAttached)
            runCurrent()

            broadcastDispatcher.sendIntentToMatchingReceiversOnly(
                context,
                Intent(UnderlayRepository.ACTION_CREATE_UNDERLAY),
            )

            assertThat(isUnderlayAttached).isTrue()
        }

    @Test
    fun isUnderlayAttached_whenDestroyed_false() =
        kosmos.runTest {
            val isUnderlayAttached by collectLastValue(underlayRepository.isUnderlayAttached)
            runCurrent()

            broadcastDispatcher.sendIntentToMatchingReceiversOnly(
                context,
                Intent(UnderlayRepository.ACTION_DESTROY_UNDERLAY),
            )

            assertThat(isUnderlayAttached).isFalse()
        }
}
+65 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.underlay.domain.interactor

import android.content.Intent
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.broadcastDispatcher
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runCurrent
import com.android.systemui.kosmos.runTest
import com.android.systemui.testKosmos
import com.android.systemui.underlay.data.repository.UnderlayRepository
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
@SmallTest
class UnderlayInteractorTest : SysuiTestCase() {
    private val kosmos = testKosmos()

    @Test
    fun isUnderlayAttached_whenCreated_true() =
        kosmos.runTest {
            val isUnderlayAttached by collectLastValue(underlayInteractor.isUnderlayAttached)
            runCurrent()

            broadcastDispatcher.sendIntentToMatchingReceiversOnly(
                context,
                Intent(UnderlayRepository.ACTION_CREATE_UNDERLAY),
            )

            assertThat(isUnderlayAttached).isTrue()
        }

    @Test
    fun isUnderlayAttached_whenDestroyed_false() =
        kosmos.runTest {
            val isUnderlayAttached by collectLastValue(underlayInteractor.isUnderlayAttached)
            runCurrent()

            broadcastDispatcher.sendIntentToMatchingReceiversOnly(
                context,
                Intent(UnderlayRepository.ACTION_DESTROY_UNDERLAY),
            )

            assertThat(isUnderlayAttached).isFalse()
        }
}
+1 −1
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ constructor(
                initialValue = false,
            )

    private companion object {
    companion object {
        const val ACTION_CREATE_UNDERLAY = "com.systemui.underlay.action.CREATE_UNDERLAY"
        const val ACTION_DESTROY_UNDERLAY = "com.systemui.underlay.action.DESTROY_UNDERLAY"
    }
Loading