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

Commit 94d0d8f6 authored by Sahil Sonar's avatar Sahil Sonar 💬
Browse files

Revert "SystemUI: Add support for udfps dim layer"

This reverts commit 4849cf76.
parent ce55d5df
Loading
Loading
Loading
Loading
+1 −35
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
     Copyright (C) 2018-2024 The LineageOS Project
     Copyright (C) 2018-2022 The LineageOS Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -18,40 +18,6 @@
    <!-- Color of the UDFPS pressed view -->
    <color name="config_udfpsColor">#ffffffff</color>

    <!-- Whether to enable framework dimming for UDFPS -->
    <bool name="config_udfpsFrameworkDimming">false</bool>

    <!-- Array of brightness-alpha LUT for framework dimming -->
    <string-array name="config_udfpsDimmingBrightnessAlphaArray" translatable="false">
          <item>0,255</item>
          <item>1,248</item>
          <item>2,242</item>
          <item>3,238</item>
          <item>4,236</item>
          <item>6,236</item>
          <item>10,234</item>
          <item>20,228</item>
          <item>30,222</item>
          <item>45,217</item>
          <item>70,209</item>
          <item>100,200</item>
          <item>150,191</item>
          <item>227,178</item>
          <item>300,167</item>
          <item>400,154</item>
          <item>500,143</item>
          <item>600,133</item>
          <item>800,117</item>
          <item>1023,109</item>
          <item>1130,95</item>
          <item>1211,89</item>
          <item>1394,79</item>
          <item>1598,69</item>
          <item>1817,53</item>
          <item>2047,46</item>
          <item>4095,0</item>
    </string-array>

    <!-- Doze: does the double tap sensor need a proximity check? -->
    <bool name="doze_double_tap_proximity_check">false</bool>

+0 −12
Original line number Diff line number Diff line
@@ -158,16 +158,6 @@ class UdfpsControllerOverlay @JvmOverloads constructor(

    private var overlayTouchListener: TouchExplorationStateChangeListener? = null

    private val useFrameworkDimming = context.resources.getBoolean(
        com.android.systemui.res.R.bool.config_udfpsFrameworkDimming
    )

    private val udfpsHelper: UdfpsHelper? = if (useFrameworkDimming) {
        UdfpsHelper(context, windowManager, shadeInteractor, requestReason)
    } else {
        null
    }

    private val coreLayoutParams = WindowManager.LayoutParams(
        WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
        0 /* flags set in computeLayoutParams() */,
@@ -293,7 +283,6 @@ class UdfpsControllerOverlay @JvmOverloads constructor(
    }

    private fun addViewNowOrLater(view: View, animation: UdfpsAnimationViewController<*>?) {
        udfpsHelper?.addDimLayer()
        if (udfpsViewPerformance()) {
            addViewRunnable = kotlinx.coroutines.Runnable {
                Trace.setCounter("UdfpsAddView", 1)
@@ -428,7 +417,6 @@ class UdfpsControllerOverlay @JvmOverloads constructor(
        if (DeviceEntryUdfpsRefactor.isEnabled) {
            udfpsDisplayModeProvider.disable(null)
        }
        udfpsHelper?.removeDimLayer()
        getTouchOverlay()?.apply {
            if (udfpsViewPerformance()) {
                if (this.parent != null) {
+0 −221
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The LineageOS 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.biometrics

import android.animation.ValueAnimator
import android.annotation.UiThread
import android.content.Context
import android.graphics.Color
import android.graphics.PixelFormat
import android.hardware.biometrics.BiometricRequestConstants.REASON_AUTH_KEYGUARD
import android.hardware.biometrics.BiometricRequestConstants.RequestReason
import android.hardware.display.DisplayManager
import android.util.Log
import android.view.Display
import android.view.View
import android.view.WindowManager
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch

private const val TAG = "UdfpsHelper"

/**
 * Facilitates implementations that use GHBM where dim layer
 * and pressed icon aren't controlled by kernel
 */
@UiThread
class UdfpsHelper(
    private val context: Context,
    private val windowManager: WindowManager,
    private val shadeInteractor: ShadeInteractor,
    @RequestReason val requestReason: Int,
    private var view: View = View(context).apply {
        setBackgroundColor(Color.BLACK)
        visibility = View.GONE
    }
) {
    private val displayManager = context.getSystemService(DisplayManager::class.java)!!
    private val isKeyguard = requestReason == REASON_AUTH_KEYGUARD
    private var newIsQsExpanded = false

    private val currentBrightness: Float get() =
        displayManager.getBrightness(Display.DEFAULT_DISPLAY)
    private val minBrightness: Float = context.resources
        .getFloat(com.android.internal.R.dimen.config_screenBrightnessSettingMinimumFloat)
    private val maxBrightness: Float = context.resources
        .getFloat(com.android.internal.R.dimen.config_screenBrightnessSettingMaximumFloat)
    private val brightnessAlphaMap: Map<Int, Int> = context.resources
        .getStringArray(com.android.systemui.res.R.array.config_udfpsDimmingBrightnessAlphaArray)
        .associate {
            val (brightness, alpha) = it.split(",").map { value -> value.trim().toInt() }
            brightness to alpha
        }

    private val dimLayoutParams = WindowManager.LayoutParams(
        WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
        0 /* flags are set in computeLayoutParams() */,
        PixelFormat.TRANSPARENT
    ).apply {
        title = "Dim Layer for UDFPS"
        fitInsetsTypes = 0
        gravity = android.view.Gravity.TOP or android.view.Gravity.LEFT
        layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
        flags = Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS or
                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
        privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY or
                WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION
        // Avoid announcing window title
        accessibilityTitle = " "
        inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_SPY
    }

    private val alphaAnimator = ValueAnimator().apply {
        duration = 800L
        addUpdateListener { animator ->
            view.alpha = animator.animatedValue as Float
            dimLayoutParams.alpha = animator.animatedValue as Float
            try {
                windowManager.updateViewLayout(view, dimLayoutParams)
            } catch (e: IllegalArgumentException) {
                Log.e(TAG, "View not attached to WindowManager", e)
            }
        }
    }

    private val displayListener = object : DisplayManager.DisplayListener {
        override fun onDisplayAdded(displayId: Int) {}

        override fun onDisplayChanged(displayId: Int) {
            if (displayId == Display.DEFAULT_DISPLAY) {
                brightnessToAlpha()
                windowManager.updateViewLayout(view, dimLayoutParams)
            }
        }

        override fun onDisplayRemoved(displayId: Int) {}
    }

    private fun interpolate(
        value: Float,
        fromMin: Int,
        fromMax: Int,
        toMin: Int,
        toMax: Int
    ): Float {
        return toMin + (value - fromMin) * (toMax - toMin) / (fromMax - fromMin)
    }

    private fun interpolateAlpha(brightness: Int): Float {
        val lowerEntry = brightnessAlphaMap.entries
            .lastOrNull { it.key <= brightness } ?: return 0f
        val upperEntry = brightnessAlphaMap.entries
            .firstOrNull { it.key >= brightness } ?: return 0f
        val (lowerBrightness, lowerAlpha) = lowerEntry
        val (upperBrightness, upperAlpha) = upperEntry

        return interpolate(
            brightness.toFloat(),
            lowerBrightness,
            upperBrightness,
            lowerAlpha,
            upperAlpha
        ).div(255.0f)
    }

    // The current function does not account for Doze state where the brightness can go lower
    // than what is set on config_screenBrightnessSettingMinimumFloat.
    // While it's possible to operate with floats, the dimming array was made by referencing
    // brightness_alpha_lut array from the kernel. This provides a comparable array.
    private fun brightnessToAlpha() {
        val adjustedBrightness =
            (currentBrightness.coerceIn(minBrightness, maxBrightness) * 4095).toInt()

        val targetAlpha = brightnessAlphaMap[adjustedBrightness]?.div(255.0f)
            ?: interpolateAlpha(adjustedBrightness)

        Log.i(TAG, "Adjusted Brightness: $adjustedBrightness, Alpha: $targetAlpha")

        alphaAnimator.setFloatValues(view.alpha, targetAlpha)
        // Set the dim for both the view and the layout
        view.alpha = targetAlpha
        dimLayoutParams.alpha = targetAlpha
    }

    fun addDimLayer() {
        brightnessToAlpha()
        windowManager.addView(view, dimLayoutParams)
    }

    fun removeDimLayer() {
        windowManager.removeView(view)
    }

    init {
        view.repeatWhenAttached {
            repeatOnLifecycle(Lifecycle.State.CREATED) {
                listenForQsExpansion(this)

                if (isKeyguard) {
                    listenForShadeTouchability(this)
                }
            }
        }

        if (!isKeyguard) {
            view.isVisible = true
        }
    }

    // We don't have ways to get temporary brightness when operating the brightness slider.
    // Therefore, the dim layer is hidden when the slider is expected to be utilized.
    private suspend fun listenForQsExpansion(scope: CoroutineScope): Job {
        return scope.launch {
            shadeInteractor.qsExpansion.collect { qsExpansion ->
                if (qsExpansion == 1f && !newIsQsExpanded) {
                    newIsQsExpanded = true
                    displayManager.registerDisplayListener(
                        displayListener, null, DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
                    )
                    view.isVisible = false
                } else if (qsExpansion == 0f && newIsQsExpanded) {
                    newIsQsExpanded = false
                    displayManager.unregisterDisplayListener(displayListener)
                    view.isVisible = true
                }
            }
        }
    }

    private suspend fun listenForShadeTouchability(scope: CoroutineScope): Job {
        return scope.launch {
            shadeInteractor.isShadeTouchable.collect {
                view.isVisible = it
                if (view.isVisible) {
                    brightnessToAlpha()
                    alphaAnimator.cancel()
                    alphaAnimator.start()
                }
            }
        }
    }
}