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

Commit 547b29d6 authored by Chris Göllner's avatar Chris Göllner
Browse files

Prepare FaceScanningProviderFactory for multiple displays

- Split interface and impl
- Turn it into an @AssistedInject class

Test: FaceScanningProviderFactoryTest
Test: Build & Run
Flag: EXEMPT no behavior changes
Bug: 362720432
Change-Id: I95df38a846ecf8bd823eeaba4bded66553668e72
parent 0b4cb06d
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -16,9 +16,14 @@

package com.android.systemui

import android.content.Context
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.decor.FaceScanningProviderFactory
import com.android.systemui.decor.FaceScanningProviderFactoryImpl
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
import dagger.multibindings.IntoSet
@@ -35,4 +40,15 @@ interface ScreenDecorationsModule {
    @Binds
    @IntoSet
    fun bindScreenDecorationsConfigListener(impl: ScreenDecorations): ConfigurationListener

    companion object {
        @Provides
        @SysUISingleton
        fun faceScanningProviderFactory(
            creator: FaceScanningProviderFactoryImpl.Creator,
            context: Context,
        ): FaceScanningProviderFactory {
            return creator.create(context)
        }
    }
}
+4 −7
Original line number Diff line number Diff line
@@ -22,18 +22,15 @@ import android.view.Display
import android.view.DisplayCutout
import android.view.DisplayInfo

class CutoutDecorProviderFactory constructor(
    private val res: Resources,
    private val display: Display?,
) : DecorProviderFactory() {
class CutoutDecorProviderFactory(private val res: Resources, private val display: Display?) :
    DecorProviderFactory {

    val displayInfo = DisplayInfo()

    override val hasProviders: Boolean
        get() {
            display?.getDisplayInfo(displayInfo) ?: run {
                Log.w(TAG, "display is null, can't update displayInfo")
            }
            display?.getDisplayInfo(displayInfo)
                ?: run { Log.w(TAG, "display is null, can't update displayInfo") }
            return DisplayCutout.getFillBuiltInDisplayCutout(res, displayInfo.uniqueId)
        }

+4 −4
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

package com.android.systemui.decor

abstract class DecorProviderFactory {
    abstract val providers: List<DecorProvider>
    abstract val hasProviders: Boolean
interface DecorProviderFactory {
    val providers: List<DecorProvider>
    val hasProviders: Boolean
}
+100 −77
Original line number Diff line number Diff line
@@ -33,23 +33,32 @@ import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.FaceScanningOverlay
import com.android.systemui.biometrics.AuthController
import com.android.systemui.biometrics.data.repository.FacePropertyRepository
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.log.ScreenDecorationsLogger
import com.android.systemui.plugins.statusbar.StatusBarStateController
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import java.util.concurrent.Executor
import javax.inject.Inject

@SysUISingleton
class FaceScanningProviderFactory @Inject constructor(
interface FaceScanningProviderFactory : DecorProviderFactory {

    fun canShowFaceScanningAnim(): Boolean

    fun shouldShowFaceScanningAnim(): Boolean
}

class FaceScanningProviderFactoryImpl
@AssistedInject
constructor(
    private val authController: AuthController,
        private val context: Context,
    @Assisted private val context: Context,
    private val statusBarStateController: StatusBarStateController,
    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
    @Main private val mainExecutor: Executor,
    private val logger: ScreenDecorationsLogger,
    private val facePropertyRepository: FacePropertyRepository,
) : DecorProviderFactory() {
) : FaceScanningProviderFactory {
    private val display = context.display
    private val displayInfo = DisplayInfo()

@@ -60,11 +69,12 @@ class FaceScanningProviderFactory @Inject constructor(
            }

            // update display info
            display?.getDisplayInfo(displayInfo) ?: run {
                Log.w(TAG, "display is null, can't update displayInfo")
            }
            display?.getDisplayInfo(displayInfo)
                ?: run { Log.w(TAG, "display is null, can't update displayInfo") }
            return DisplayCutout.getFillBuiltInDisplayCutout(
                    context.resources, displayInfo.uniqueId)
                context.resources,
                displayInfo.uniqueId,
            )
        }

    override val providers: List<DecorProvider>
@@ -96,14 +106,20 @@ class FaceScanningProviderFactory @Inject constructor(
            }
        }

    fun canShowFaceScanningAnim(): Boolean {
    override fun canShowFaceScanningAnim(): Boolean {
        return hasProviders && keyguardUpdateMonitor.isFaceEnabledAndEnrolled
    }

    fun shouldShowFaceScanningAnim(): Boolean {
    override fun shouldShowFaceScanningAnim(): Boolean {
        return canShowFaceScanningAnim() &&
            (keyguardUpdateMonitor.isFaceDetectionRunning || authController.isShowing)
    }

    // Using the name "Creator" so that it doesn't become "...FactoryFactory".
    @AssistedFactory
    interface Creator {
        fun create(context: Context): FaceScanningProviderFactoryImpl
    }
}

class FaceScanningOverlayProviderImpl(
@@ -122,7 +138,7 @@ class FaceScanningOverlayProviderImpl(
        reloadToken: Int,
        @Surface.Rotation rotation: Int,
        tintColor: Int,
        displayUniqueId: String?
        displayUniqueId: String?,
    ) {
        (view.layoutParams as FrameLayout.LayoutParams).let {
            updateLayoutParams(it, rotation)
@@ -138,9 +154,10 @@ class FaceScanningOverlayProviderImpl(
        context: Context,
        parent: ViewGroup,
        @Surface.Rotation rotation: Int,
        tintColor: Int
        tintColor: Int,
    ): View {
        val view = FaceScanningOverlay(
        val view =
            FaceScanningOverlay(
                context,
                alignedBound,
                statusBarStateController,
@@ -151,8 +168,11 @@ class FaceScanningOverlayProviderImpl(
            )
        view.id = viewId
        view.setColor(tintColor)
        FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT).let {
        FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT,
            )
            .let {
                updateLayoutParams(it, rotation)
                parent.addView(view, it)
            }
@@ -161,24 +181,24 @@ class FaceScanningOverlayProviderImpl(

    private fun updateLayoutParams(
        layoutParams: FrameLayout.LayoutParams,
        @Surface.Rotation rotation: Int
        @Surface.Rotation rotation: Int,
    ) {
        layoutParams.let { lp ->
            lp.width = ViewGroup.LayoutParams.MATCH_PARENT
            lp.height = ViewGroup.LayoutParams.MATCH_PARENT
            logger.faceSensorLocation(facePropertyRepository.sensorLocation.value)
            facePropertyRepository.sensorLocation.value?.y?.let {
                faceAuthSensorHeight ->
            facePropertyRepository.sensorLocation.value?.y?.let { faceAuthSensorHeight ->
                val faceScanningHeight = (faceAuthSensorHeight * 2)
                when (rotation) {
                    Surface.ROTATION_0, Surface.ROTATION_180 ->
                        lp.height = faceScanningHeight
                    Surface.ROTATION_90, Surface.ROTATION_270 ->
                        lp.width = faceScanningHeight
                    Surface.ROTATION_0,
                    Surface.ROTATION_180 -> lp.height = faceScanningHeight
                    Surface.ROTATION_90,
                    Surface.ROTATION_270 -> lp.width = faceScanningHeight
                }
            }

            lp.gravity = when (rotation) {
            lp.gravity =
                when (rotation) {
                    Surface.ROTATION_0 -> Gravity.TOP or Gravity.START
                    Surface.ROTATION_90 -> Gravity.LEFT or Gravity.START
                    Surface.ROTATION_180 -> Gravity.BOTTOM or Gravity.END
@@ -209,19 +229,22 @@ fun DisplayCutout.getBoundBaseOnCurrentRotation(): List<Int> {
fun Int.baseOnRotation0(@DisplayCutout.BoundsPosition currentRotation: Int): Int {
    return when (currentRotation) {
        Surface.ROTATION_0 -> this
        Surface.ROTATION_90 -> when (this) {
        Surface.ROTATION_90 ->
            when (this) {
                BOUNDS_POSITION_LEFT -> BOUNDS_POSITION_TOP
                BOUNDS_POSITION_TOP -> BOUNDS_POSITION_RIGHT
                BOUNDS_POSITION_RIGHT -> BOUNDS_POSITION_BOTTOM
                else /* BOUNDS_POSITION_BOTTOM */ -> BOUNDS_POSITION_LEFT
            }
        Surface.ROTATION_270 -> when (this) {
        Surface.ROTATION_270 ->
            when (this) {
                BOUNDS_POSITION_LEFT -> BOUNDS_POSITION_BOTTOM
                BOUNDS_POSITION_TOP -> BOUNDS_POSITION_LEFT
                BOUNDS_POSITION_RIGHT -> BOUNDS_POSITION_TOP
                else /* BOUNDS_POSITION_BOTTOM */ -> BOUNDS_POSITION_RIGHT
            }
        else /* Surface.ROTATION_180 */ -> when (this) {
        else /* Surface.ROTATION_180 */ ->
            when (this) {
                BOUNDS_POSITION_LEFT -> BOUNDS_POSITION_RIGHT
                BOUNDS_POSITION_TOP -> BOUNDS_POSITION_BOTTOM
                BOUNDS_POSITION_RIGHT -> BOUNDS_POSITION_LEFT
+16 −13
Original line number Diff line number Diff line
@@ -23,19 +23,18 @@ import android.view.LayoutInflater
import android.view.Surface
import android.view.View
import android.view.ViewGroup
import com.android.systemui.res.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.res.R
import javax.inject.Inject

/**
 * Provides privacy dot views for each orientation. The PrivacyDot orientation and visibility
 * of the privacy dot views are controlled by the PrivacyDotViewController.
 * Provides privacy dot views for each orientation. The PrivacyDot orientation and visibility of the
 * privacy dot views are controlled by the PrivacyDotViewController.
 */
@SysUISingleton
open class PrivacyDotDecorProviderFactory @Inject constructor(
    @Main private val res: Resources
) : DecorProviderFactory() {
open class PrivacyDotDecorProviderFactory @Inject constructor(@Main private val res: Resources) :
    DecorProviderFactory {

    private val isPrivacyDotEnabled: Boolean
        get() = res.getBoolean(R.bool.config_enablePrivacyDot)
@@ -51,22 +50,26 @@ open class PrivacyDotDecorProviderFactory @Inject constructor(
                        viewId = R.id.privacy_dot_top_left_container,
                        alignedBound1 = DisplayCutout.BOUNDS_POSITION_TOP,
                        alignedBound2 = DisplayCutout.BOUNDS_POSITION_LEFT,
                        layoutId = R.layout.privacy_dot_top_left),
                        layoutId = R.layout.privacy_dot_top_left,
                    ),
                    PrivacyDotCornerDecorProviderImpl(
                        viewId = R.id.privacy_dot_top_right_container,
                        alignedBound1 = DisplayCutout.BOUNDS_POSITION_TOP,
                        alignedBound2 = DisplayCutout.BOUNDS_POSITION_RIGHT,
                        layoutId = R.layout.privacy_dot_top_right),
                        layoutId = R.layout.privacy_dot_top_right,
                    ),
                    PrivacyDotCornerDecorProviderImpl(
                        viewId = R.id.privacy_dot_bottom_left_container,
                        alignedBound1 = DisplayCutout.BOUNDS_POSITION_BOTTOM,
                        alignedBound2 = DisplayCutout.BOUNDS_POSITION_LEFT,
                        layoutId = R.layout.privacy_dot_bottom_left),
                        layoutId = R.layout.privacy_dot_bottom_left,
                    ),
                    PrivacyDotCornerDecorProviderImpl(
                        viewId = R.id.privacy_dot_bottom_right_container,
                        alignedBound1 = DisplayCutout.BOUNDS_POSITION_BOTTOM,
                        alignedBound2 = DisplayCutout.BOUNDS_POSITION_RIGHT,
                        layoutId = R.layout.privacy_dot_bottom_right)
                        layoutId = R.layout.privacy_dot_bottom_right,
                    ),
                )
            } else {
                emptyList()
@@ -78,7 +81,7 @@ class PrivacyDotCornerDecorProviderImpl(
    override val viewId: Int,
    @DisplayCutout.BoundsPosition override val alignedBound1: Int,
    @DisplayCutout.BoundsPosition override val alignedBound2: Int,
    private val layoutId: Int
    private val layoutId: Int,
) : CornerDecorProvider() {

    override fun onReloadResAndMeasure(
@@ -86,7 +89,7 @@ class PrivacyDotCornerDecorProviderImpl(
        reloadToken: Int,
        rotation: Int,
        tintColor: Int,
        displayUniqueId: String?
        displayUniqueId: String?,
    ) {
        // Do nothing here because it is handled inside PrivacyDotViewController
    }
@@ -95,7 +98,7 @@ class PrivacyDotCornerDecorProviderImpl(
        context: Context,
        parent: ViewGroup,
        @Surface.Rotation rotation: Int,
        tintColor: Int
        tintColor: Int,
    ): View {
        LayoutInflater.from(context).inflate(layoutId, parent, true)
        return parent.getChildAt(parent.childCount - 1 /* latest new added child */)
Loading