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

Commit 55ba6935 authored by Chris Göllner's avatar Chris Göllner Committed by Chris Göllner
Browse files

Clean up launched flag "privacy_dot_unfold_wrong_corner_fix"

Flag: EXEMPT removing privacy_dot_unfold_wrong_corner_fix
Test: NA
Bug: 339335643
Change-Id: Ica30adee1ec23fbbebff6f69b706a14577fea4f1
parent c4c834fe
Loading
Loading
Loading
Loading
+0 −10
Original line number Original line Diff line number Diff line
@@ -1069,16 +1069,6 @@ flag {
  }
  }
}
}


flag {
  namespace: "systemui"
  name: "privacy_dot_unfold_wrong_corner_fix"
  description: "Fixes an issue where the privacy dot is at the wrong corner after unfolding/folding."
  bug: "339335643"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}

flag {
flag {
  name: "validate_keyboard_shortcut_helper_icon_uri"
  name: "validate_keyboard_shortcut_helper_icon_uri"
  namespace: "systemui"
  namespace: "systemui"
+2 −28
Original line number Original line Diff line number Diff line
@@ -18,8 +18,6 @@ package com.android.systemui.statusbar.events


import android.graphics.Point
import android.graphics.Point
import android.graphics.Rect
import android.graphics.Rect
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.testing.TestableLooper.RunWithLooper
import android.testing.TestableLooper.RunWithLooper
import android.view.Display
import android.view.Display
import android.view.DisplayAdjustments
import android.view.DisplayAdjustments
@@ -28,7 +26,6 @@ import android.widget.FrameLayout
import android.widget.FrameLayout.LayoutParams.UNSPECIFIED_GRAVITY
import android.widget.FrameLayout.LayoutParams.UNSPECIFIED_GRAVITY
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.filters.SmallTest
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestCase
import com.android.systemui.res.R
import com.android.systemui.res.R
import com.android.systemui.statusbar.FakeStatusBarStateController
import com.android.systemui.statusbar.FakeStatusBarStateController
@@ -297,8 +294,7 @@ class PrivacyDotViewControllerTest : SysuiTestCase() {
    }
    }


    @Test
    @Test
    @EnableFlags(Flags.FLAG_PRIVACY_DOT_UNFOLD_WRONG_CORNER_FIX)
    fun initialize_newViews_gravityIsUpdated() {
    fun initialize_newViews_fixFlagEnabled_gravityIsUpdated() {
        val newTopLeftView = initDotView()
        val newTopLeftView = initDotView()
        val newTopRightView = initDotView()
        val newTopRightView = initDotView()
        val newBottomLeftView = initDotView()
        val newBottomLeftView = initDotView()
@@ -318,28 +314,6 @@ class PrivacyDotViewControllerTest : SysuiTestCase() {
            .isNotEqualTo(UNSPECIFIED_GRAVITY)
            .isNotEqualTo(UNSPECIFIED_GRAVITY)
    }
    }


    @Test
    @DisableFlags(Flags.FLAG_PRIVACY_DOT_UNFOLD_WRONG_CORNER_FIX)
    fun initialize_newViews_fixFlagDisabled_gravityIsNotUpdated() {
        val newTopLeftView = initDotView()
        val newTopRightView = initDotView()
        val newBottomLeftView = initDotView()
        val newBottomRightView = initDotView()
        setRotation(ROTATION_LANDSCAPE) // Bottom right used in landscape

        val controller = createAndInitializeController()
        // Re-init with different views, but same rotation
        controller.initialize(
            newTopLeftView,
            newTopRightView,
            newBottomLeftView,
            newBottomRightView
        )

        assertThat((newBottomRightView.layoutParams as FrameLayout.LayoutParams).gravity)
            .isEqualTo(UNSPECIFIED_GRAVITY)
    }

    private fun setRotation(rotation: Int) {
    private fun setRotation(rotation: Int) {
        whenever(mockDisplay.rotation).thenReturn(rotation)
        whenever(mockDisplay.rotation).thenReturn(rotation)
    }
    }
+107 −108
Original line number Original line Diff line number Diff line
@@ -26,7 +26,6 @@ import android.widget.FrameLayout
import androidx.core.animation.Animator
import androidx.core.animation.Animator
import com.android.app.animation.Interpolators
import com.android.app.animation.Interpolators
import com.android.internal.annotations.GuardedBy
import com.android.internal.annotations.GuardedBy
import com.android.systemui.Flags.privacyDotUnfoldWrongCornerFix
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dagger.qualifiers.Main
@@ -45,10 +44,10 @@ 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_SEASCAPE
import com.android.systemui.util.leak.RotationUtils.ROTATION_UPSIDE_DOWN
import com.android.systemui.util.leak.RotationUtils.ROTATION_UPSIDE_DOWN
import com.android.systemui.util.leak.RotationUtils.Rotation
import com.android.systemui.util.leak.RotationUtils.Rotation
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import java.util.concurrent.Executor
import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch


/**
/**
 * Understands how to keep the persistent privacy dot in the corner of the screen in
 * Understands how to keep the persistent privacy dot in the corner of the screen in
@@ -61,12 +60,13 @@ import javax.inject.Inject
 * Views will match the status bar top padding and status bar height so that the dot can appear to
 * Views will match the status bar top padding and status bar height so that the dot can appear to
 * reside directly after the status bar system contents (basically after the battery).
 * reside directly after the status bar system contents (basically after the battery).
 *
 *
 * NOTE: any operation that modifies views directly must run on the provided executor, because
 * NOTE: any operation that modifies views directly must run on the provided executor, because these
 * these views are owned by ScreenDecorations and it runs in its own thread
 * views are owned by ScreenDecorations and it runs in its own thread
 */
 */

@SysUISingleton
@SysUISingleton
open class PrivacyDotViewController @Inject constructor(
open class PrivacyDotViewController
@Inject
constructor(
    @Main private val mainExecutor: Executor,
    @Main private val mainExecutor: Executor,
    @Application scope: CoroutineScope,
    @Application scope: CoroutineScope,
    private val stateController: StatusBarStateController,
    private val stateController: StatusBarStateController,
@@ -90,6 +90,7 @@ open class PrivacyDotViewController @Inject constructor(
            field = value
            field = value
            scheduleUpdate()
            scheduleUpdate()
        }
        }

    private val lock = Object()
    private val lock = Object()
    private var cancelRunnable: Runnable? = null
    private var cancelRunnable: Runnable? = null


@@ -106,14 +107,17 @@ open class PrivacyDotViewController @Inject constructor(
        get() = field
        get() = field


    init {
    init {
        contentInsetsProvider.addCallback(object : StatusBarContentInsetsChangedListener {
        contentInsetsProvider.addCallback(
            object : StatusBarContentInsetsChangedListener {
                override fun onStatusBarContentInsetsChanged() {
                override fun onStatusBarContentInsetsChanged() {
                    dlog("onStatusBarContentInsetsChanged: ")
                    dlog("onStatusBarContentInsetsChanged: ")
                    setNewLayoutRects()
                    setNewLayoutRects()
                }
                }
        })
            }
        )


        configurationController.addCallback(object : ConfigurationController.ConfigurationListener {
        configurationController.addCallback(
            object : ConfigurationController.ConfigurationListener {
                override fun onLayoutDirectionChanged(isRtl: Boolean) {
                override fun onLayoutDirectionChanged(isRtl: Boolean) {
                    uiExecutor?.execute {
                    uiExecutor?.execute {
                        // If rtl changed, hide all dotes until the next state resolves
                        // If rtl changed, hide all dotes until the next state resolves
@@ -121,16 +125,16 @@ open class PrivacyDotViewController @Inject constructor(


                        synchronized(this) {
                        synchronized(this) {
                            val corner = selectDesignatedCorner(nextViewState.rotation, isRtl)
                            val corner = selectDesignatedCorner(nextViewState.rotation, isRtl)
                        nextViewState = nextViewState.copy(
                            nextViewState =
                                layoutRtl = isRtl,
                                nextViewState.copy(layoutRtl = isRtl, designatedCorner = corner)
                                designatedCorner = corner
                        }
                        )
                    }
                    }
                }
                }
            }
            }
        })
        )


        stateController.addCallback(object : StatusBarStateController.StateListener {
        stateController.addCallback(
            object : StatusBarStateController.StateListener {
                override fun onExpandedChanged(isExpanded: Boolean) {
                override fun onExpandedChanged(isExpanded: Boolean) {
                    updateStatusBarState()
                    updateStatusBarState()
                }
                }
@@ -138,14 +142,13 @@ open class PrivacyDotViewController @Inject constructor(
                override fun onStateChanged(newState: Int) {
                override fun onStateChanged(newState: Int) {
                    updateStatusBarState()
                    updateStatusBarState()
                }
                }
        })
            }
        )


        scope.launch {
        scope.launch {
            shadeInteractor?.isQsExpanded?.collect { isQsExpanded ->
            shadeInteractor?.isQsExpanded?.collect { isQsExpanded ->
                dlog("setQsExpanded $isQsExpanded")
                dlog("setQsExpanded $isQsExpanded")
                synchronized(lock) {
                synchronized(lock) { nextViewState = nextViewState.copy(qsExpanded = isQsExpanded) }
                    nextViewState = nextViewState.copy(qsExpanded = isQsExpanded)
                }
            }
            }
        }
        }
    }
    }
@@ -179,11 +182,13 @@ open class PrivacyDotViewController @Inject constructor(
        val paddingTop = contentInsetsProvider.getStatusBarPaddingTop(rot)
        val paddingTop = contentInsetsProvider.getStatusBarPaddingTop(rot)


        synchronized(lock) {
        synchronized(lock) {
            nextViewState = nextViewState.copy(
            nextViewState =
                nextViewState.copy(
                    rotation = rot,
                    rotation = rot,
                    paddingTop = paddingTop,
                    paddingTop = paddingTop,
                    designatedCorner = newCorner,
                    designatedCorner = newCorner,
                    cornerIndex = index)
                    cornerIndex = index
                )
        }
        }
    }
    }


@@ -241,8 +246,8 @@ open class PrivacyDotViewController @Inject constructor(
            }
            }


            // Set the dot's view gravity to hug the status bar
            // Set the dot's view gravity to hug the status bar
            (corner.requireViewById<View>(R.id.privacy_dot)
            (corner.requireViewById<View>(R.id.privacy_dot).layoutParams
                    .layoutParams as FrameLayout.LayoutParams)
                    as FrameLayout.LayoutParams)
                .gravity = rotatedCorner.innerGravity()
                .gravity = rotatedCorner.innerGravity()
        }
        }
    }
    }
@@ -353,10 +358,7 @@ open class PrivacyDotViewController @Inject constructor(
                clearAnimation()
                clearAnimation()
                visibility = View.VISIBLE
                visibility = View.VISIBLE
                alpha = 0f
                alpha = 0f
                animate()
                animate().alpha(1.0f).setDuration(300).start()
                    .alpha(1.0f)
                    .setDuration(300)
                    .start()
            }
            }
        }
        }
    }
    }
@@ -405,15 +407,21 @@ open class PrivacyDotViewController @Inject constructor(


    private fun widthForCorner(corner: Int, left: Int, right: Int): Int {
    private fun widthForCorner(corner: Int, left: Int, right: Int): Int {
        return when (corner) {
        return when (corner) {
            TOP_LEFT, BOTTOM_LEFT -> left
            TOP_LEFT,
            TOP_RIGHT, BOTTOM_RIGHT -> right
            BOTTOM_LEFT -> left
            TOP_RIGHT,
            BOTTOM_RIGHT -> right
            else -> throw IllegalArgumentException("Unknown corner")
            else -> throw IllegalArgumentException("Unknown corner")
        }
        }
    }
    }


    fun initialize(topLeft: View, topRight: View, bottomLeft: View, bottomRight: View) {
    fun initialize(topLeft: View, topRight: View, bottomLeft: View, bottomRight: View) {
        if (this::tl.isInitialized && this::tr.isInitialized &&
        if (
                this::bl.isInitialized && this::br.isInitialized) {
            this::tl.isInitialized &&
                this::tr.isInitialized &&
                this::bl.isInitialized &&
                this::br.isInitialized
        ) {
            if (tl == topLeft && tr == topRight && bl == bottomLeft && br == bottomRight) {
            if (tl == topLeft && tr == topRight && bl == bottomLeft && br == bottomRight) {
                return
                return
            }
            }
@@ -430,19 +438,17 @@ open class PrivacyDotViewController @Inject constructor(


        val index = dc.cornerIndex()
        val index = dc.cornerIndex()


        mainExecutor.execute {
        mainExecutor.execute { animationScheduler.addCallback(systemStatusAnimationCallback) }
            animationScheduler.addCallback(systemStatusAnimationCallback)
        }


        val left = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_SEASCAPE)
        val left = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_SEASCAPE)
        val top = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_NONE)
        val top = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_NONE)
        val right = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_LANDSCAPE)
        val right = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_LANDSCAPE)
        val bottom = contentInsetsProvider
        val bottom = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_UPSIDE_DOWN)
                .getStatusBarContentAreaForRotation(ROTATION_UPSIDE_DOWN)
        val paddingTop = contentInsetsProvider.getStatusBarPaddingTop()
        val paddingTop = contentInsetsProvider.getStatusBarPaddingTop()


        synchronized(lock) {
        synchronized(lock) {
            nextViewState = nextViewState.copy(
            nextViewState =
                nextViewState.copy(
                    viewInitialized = true,
                    viewInitialized = true,
                    designatedCorner = dc,
                    designatedCorner = dc,
                    cornerIndex = index,
                    cornerIndex = index,
@@ -457,9 +463,7 @@ open class PrivacyDotViewController @Inject constructor(
    }
    }


    private fun updateStatusBarState() {
    private fun updateStatusBarState() {
        synchronized(lock) {
        synchronized(lock) { nextViewState = nextViewState.copy(shadeExpanded = isShadeInQs()) }
            nextViewState = nextViewState.copy(shadeExpanded = isShadeInQs())
        }
    }
    }


    /**
    /**
@@ -476,9 +480,7 @@ open class PrivacyDotViewController @Inject constructor(
        dlog("scheduleUpdate: ")
        dlog("scheduleUpdate: ")


        cancelRunnable?.run()
        cancelRunnable?.run()
        cancelRunnable = uiExecutor?.executeDelayed({
        cancelRunnable = uiExecutor?.executeDelayed({ processNextViewState() }, 100)
            processNextViewState()
        }, 100)
    }
    }


    @UiThread
    @UiThread
@@ -486,9 +488,7 @@ open class PrivacyDotViewController @Inject constructor(
        dlog("processNextViewState: ")
        dlog("processNextViewState: ")


        val newState: ViewState
        val newState: ViewState
        synchronized(lock) {
        synchronized(lock) { newState = nextViewState.copy() }
            newState = nextViewState.copy()
        }


        resolveState(newState)
        resolveState(newState)
    }
    }
@@ -508,7 +508,7 @@ open class PrivacyDotViewController @Inject constructor(


        val designatedCornerChanged = state.designatedCorner != currentViewState.designatedCorner
        val designatedCornerChanged = state.designatedCorner != currentViewState.designatedCorner
        val rotationChanged = state.rotation != currentViewState.rotation
        val rotationChanged = state.rotation != currentViewState.rotation
        if (rotationChanged || (designatedCornerChanged && privacyDotUnfoldWrongCornerFix())) {
        if (rotationChanged || designatedCornerChanged) {
            // A rotation has started, hide the views to avoid flicker
            // A rotation has started, hide the views to avoid flicker
            updateRotations(state.rotation, state.paddingTop)
            updateRotations(state.rotation, state.paddingTop)
        }
        }
@@ -550,9 +550,11 @@ open class PrivacyDotViewController @Inject constructor(
                contentDescr: String?
                contentDescr: String?
            ): Animator? {
            ): Animator? {
                synchronized(lock) {
                synchronized(lock) {
                nextViewState = nextViewState.copy(
                    nextViewState =
                        nextViewState.copy(
                            systemPrivacyEventIsActive = true,
                            systemPrivacyEventIsActive = true,
                        contentDescription = contentDescr)
                            contentDescription = contentDescr
                        )
                }
                }


                return null
                return null
@@ -579,8 +581,7 @@ open class PrivacyDotViewController @Inject constructor(
        val left = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_SEASCAPE)
        val left = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_SEASCAPE)
        val top = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_NONE)
        val top = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_NONE)
        val right = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_LANDSCAPE)
        val right = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_LANDSCAPE)
        val bottom = contentInsetsProvider
        val bottom = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_UPSIDE_DOWN)
                .getStatusBarContentAreaForRotation(ROTATION_UPSIDE_DOWN)


        return listOf(left, top, right, bottom)
        return listOf(left, top, right, bottom)
    }
    }
@@ -589,7 +590,8 @@ open class PrivacyDotViewController @Inject constructor(
        val rects = getLayoutRects()
        val rects = getLayoutRects()


        synchronized(lock) {
        synchronized(lock) {
            nextViewState = nextViewState.copy(
            nextViewState =
                nextViewState.copy(
                    seascapeRect = rects[0],
                    seascapeRect = rects[0],
                    portraitRect = rects[1],
                    portraitRect = rects[1],
                    landscapeRect = rects[2],
                    landscapeRect = rects[2],
@@ -600,6 +602,7 @@ open class PrivacyDotViewController @Inject constructor(


    interface ShowingListener {
    interface ShowingListener {
        fun onPrivacyDotShown(v: View?)
        fun onPrivacyDotShown(v: View?)

        fun onPrivacyDotHidden(v: View?)
        fun onPrivacyDotHidden(v: View?)
    }
    }
}
}
@@ -647,22 +650,18 @@ private fun Int.innerGravity(): Int {


data class ViewState(
data class ViewState(
    val viewInitialized: Boolean = false,
    val viewInitialized: Boolean = false,

    val systemPrivacyEventIsActive: Boolean = false,
    val systemPrivacyEventIsActive: Boolean = false,
    val shadeExpanded: Boolean = false,
    val shadeExpanded: Boolean = false,
    val qsExpanded: Boolean = false,
    val qsExpanded: Boolean = false,

    val portraitRect: Rect? = null,
    val portraitRect: Rect? = null,
    val landscapeRect: Rect? = null,
    val landscapeRect: Rect? = null,
    val upsideDownRect: Rect? = null,
    val upsideDownRect: Rect? = null,
    val seascapeRect: Rect? = null,
    val seascapeRect: Rect? = null,
    val layoutRtl: Boolean = false,
    val layoutRtl: Boolean = false,

    val rotation: Int = 0,
    val rotation: Int = 0,
    val paddingTop: Int = 0,
    val paddingTop: Int = 0,
    val cornerIndex: Int = -1,
    val cornerIndex: Int = -1,
    val designatedCorner: View? = null,
    val designatedCorner: View? = null,

    val contentDescription: String? = null
    val contentDescription: String? = null
) {
) {
    fun shouldShowDot(): Boolean {
    fun shouldShowDot(): Boolean {