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

Commit 09435f86 authored by Nicolo' Mazzucato's avatar Nicolo' Mazzucato
Browse files

Fix ConnectedDisplayDialog after rotation and in landscape on small screens

The appropriate layout params were not set after a configuration change.

+ Added PRIVATE_FLAG_NO_MOVE_ANIMATION to avoid a weird animation when the phone is rotated
+ Set not edge to edge while in landscape (on small screens)

Test: MirroringConfirmationDialogTest, MirroringConfirmationDialogScerenshotTest
Fixes: 306124601
Change-Id: Iec6fe1cbbfdc68adc49c332c15add1333fed7590
parent 57cb73f2
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -46,4 +46,7 @@
     For now, this value has effect only when flag lockscreen.enable_landscape is enabled.
     TODO (b/293252410) - change this comment/resource when flag is enabled -->
    <bool name="force_config_use_split_notification_shade">true</bool>

    <!-- Whether to show bottom sheets edge to edge -->
    <bool name="config_edgeToEdgeBottomSheetDialog">false</bool>
</resources>
+3 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.view.View
import android.widget.TextView
import com.android.systemui.res.R
import com.android.systemui.statusbar.phone.SystemUIBottomSheetDialog
import com.android.systemui.statusbar.policy.ConfigurationController

/**
 * Dialog used to decide what to do with a connected display.
@@ -32,8 +33,9 @@ class MirroringConfirmationDialog(
    context: Context,
    private val onStartMirroringClickListener: View.OnClickListener,
    private val onCancelMirroring: View.OnClickListener,
    configurationController: ConfigurationController? = null,
    theme: Int = R.style.Theme_SystemUI_Dialog,
) : SystemUIBottomSheetDialog(context, theme) {
) : SystemUIBottomSheetDialog(context, configurationController, theme) {

    private lateinit var mirrorButton: TextView
    private lateinit var dismissButton: TextView
+5 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor
import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor.PendingDisplay
import com.android.systemui.display.ui.view.MirroringConfirmationDialog
import com.android.systemui.statusbar.policy.ConfigurationController
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
@@ -41,7 +42,8 @@ constructor(
    private val context: Context,
    private val connectedDisplayInteractor: ConnectedDisplayInteractor,
    @Application private val scope: CoroutineScope,
    @Background private val bgDispatcher: CoroutineDispatcher
    @Background private val bgDispatcher: CoroutineDispatcher,
    private val configurationController: ConfigurationController
) {

    private var dialog: Dialog? = null
@@ -71,7 +73,8 @@ constructor(
                    onCancelMirroring = {
                        scope.launch(bgDispatcher) { pendingDisplay.ignore() }
                        hideDialog()
                    }
                    },
                    configurationController
                )
                .apply { show() }
    }
+48 −19
Original line number Diff line number Diff line
@@ -17,42 +17,71 @@ package com.android.systemui.statusbar.phone

import android.app.Dialog
import android.content.Context
import android.content.res.Configuration
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.Gravity
import android.view.WindowManager
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.view.WindowManager.LayoutParams.MATCH_PARENT
import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION
import android.view.WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS
import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL
import com.android.systemui.res.R
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener

/** A dialog shown as a bottom sheet. */
open class SystemUIBottomSheetDialog(
    context: Context,
    theme: Int = R.style.Theme_SystemUI_Dialog,
    private val configurationController: ConfigurationController? = null,
    theme: Int = R.style.Theme_SystemUI_Dialog
) : Dialog(context, theme) {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setupWindow()
        setupEdgeToEdge()
        setCanceledOnTouchOutside(true)
    }

    private fun setupWindow() {
        window?.apply {
            setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL)
            addPrivateFlags(WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS)

            setType(TYPE_STATUS_BAR_SUB_PANEL)
            addPrivateFlags(SYSTEM_FLAG_SHOW_FOR_ALL_USERS or PRIVATE_FLAG_NO_MOVE_ANIMATION)
            setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
            setGravity(Gravity.BOTTOM)
            decorView.setPadding(0, 0, 0, 0)
            attributes =
                attributes.apply {
                    fitInsetsSides = 0
                    horizontalMargin = 0f
                }
        }
    }

    private fun setupEdgeToEdge() {
        val edgeToEdgeHorizontally =
            context.resources.getBoolean(R.bool.config_edgeToEdgeBottomSheetDialog)
            if (edgeToEdgeHorizontally) {
                decorView.setPadding(0, 0, 0, 0)
                setLayout(
                    WindowManager.LayoutParams.MATCH_PARENT,
                    WindowManager.LayoutParams.WRAP_CONTENT
                )
        val width = if (edgeToEdgeHorizontally) MATCH_PARENT else WRAP_CONTENT
        val height = WRAP_CONTENT
        window?.setLayout(width, height)
    }

                val lp = attributes
                lp.fitInsetsSides = 0
                lp.horizontalMargin = 0f
                attributes = lp
    override fun onStart() {
        super.onStart()
        configurationController?.addCallback(onConfigChanged)
    }

    override fun onStop() {
        super.onStop()
        configurationController?.removeCallback(onConfigChanged)
    }

    private val onConfigChanged =
        object : ConfigurationListener {
            override fun onConfigChanged(newConfig: Configuration?) {
                super.onConfigChanged(newConfig)
                setupEdgeToEdge()
            }
        setCanceledOnTouchOutside(true)
        }
}
+56 −0
Original line number Diff line number Diff line
/*
 * 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.statusbar.phone

import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
import kotlin.test.Test
import org.junit.Before
import org.junit.runner.RunWith
import org.mockito.Mockito.verify

@SmallTest
@RunWith(AndroidTestingRunner::class)
@RunWithLooper(setAsMainLooper = true)
class SystemUIBottomSheetDialogTest : SysuiTestCase() {

    private val configurationController = mock<ConfigurationController>()

    private lateinit var dialog: SystemUIBottomSheetDialog

    @Before
    fun setup() {
        dialog = SystemUIBottomSheetDialog(mContext, configurationController)
    }

    @Test
    fun onStart_registersConfigCallback() {
        dialog.show()

        verify(configurationController).addCallback(any())
    }

    @Test
    fun onStop_unregisterConfigCallback() {
        dialog.show()
        dialog.dismiss()

        verify(configurationController).removeCallback(any())
    }
}