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

Commit d31ffd3c authored by Lucas Dupin's avatar Lucas Dupin
Browse files

Fix BlurUtils crash

We need to abort the operation if the given SurfaceControl is invalid.

Test: atest BlurUtilsTest
Fixes: 148110676
Change-Id: Iaed655e06d48f4d7dd6ee2df25838188e24813c6
parent 89730404
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.os.SystemProperties
import android.util.MathUtils
import android.view.SurfaceControl
import android.view.ViewRootImpl
import androidx.annotation.VisibleForTesting
import com.android.internal.util.IndentingPrintWriter
import com.android.systemui.DumpController
import com.android.systemui.Dumpable
@@ -33,7 +34,7 @@ import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class BlurUtils @Inject constructor(
open class BlurUtils @Inject constructor(
    @Main private val resources: Resources,
    val dumpController: DumpController
) : Dumpable {
@@ -63,22 +64,28 @@ class BlurUtils @Inject constructor(
     * @param radius blur radius in pixels.
     */
    fun applyBlur(viewRootImpl: ViewRootImpl?, radius: Int) {
        if (viewRootImpl == null || !supportsBlursOnWindows()) {
        if (viewRootImpl == null || !viewRootImpl.surfaceControl.isValid ||
                !supportsBlursOnWindows()) {
            return
        }
        SurfaceControl.Transaction().use {
        createTransaction().use {
            it.setBackgroundBlurRadius(viewRootImpl.surfaceControl, radius)
            it.apply()
        }
    }

    @VisibleForTesting
    open fun createTransaction(): SurfaceControl.Transaction {
        return SurfaceControl.Transaction()
    }

    /**
     * If this device can render blurs.
     *
     * @see android.view.SurfaceControl.Transaction#setBackgroundBlurRadius(SurfaceControl, int)
     * @return {@code true} when supported.
     */
    fun supportsBlursOnWindows(): Boolean {
    open fun supportsBlursOnWindows(): Boolean {
        return blurSysProp && ActivityManager.isHighEndGfx()
    }

+82 −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.statusbar

import android.content.res.Resources
import android.view.SurfaceControl
import android.view.ViewRootImpl
import androidx.test.filters.SmallTest
import com.android.systemui.DumpController
import com.android.systemui.SysuiTestCase
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.Mockito.eq
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations

@SmallTest
class BlurUtilsTest : SysuiTestCase() {

    @Mock lateinit var resources: Resources
    @Mock lateinit var dumpController: DumpController
    @Mock lateinit var transaction: SurfaceControl.Transaction
    lateinit var blurUtils: BlurUtils

    @Before
    fun setup() {
        MockitoAnnotations.initMocks(this)
        blurUtils = TestableBlurUtils()
    }

    @Test
    fun testApplyBlur_noViewRoot_doesntCrash() {
        blurUtils.applyBlur(null /* viewRootImple */, 10 /* radius */)
    }

    @Test
    fun testApplyBlur_invalidSurfaceControl() {
        val surfaceControl = mock(SurfaceControl::class.java)
        val viewRootImpl = mock(ViewRootImpl::class.java)
        `when`(viewRootImpl.surfaceControl).thenReturn(surfaceControl)
        blurUtils.applyBlur(viewRootImpl, 10 /* radius */)
    }

    @Test
    fun testApplyBlur_success() {
        val radius = 10
        val surfaceControl = mock(SurfaceControl::class.java)
        val viewRootImpl = mock(ViewRootImpl::class.java)
        `when`(viewRootImpl.surfaceControl).thenReturn(surfaceControl)
        `when`(surfaceControl.isValid).thenReturn(true)
        blurUtils.applyBlur(viewRootImpl, radius)
        verify(transaction).setBackgroundBlurRadius(eq(surfaceControl), eq(radius))
        verify(transaction).apply()
    }

    inner class TestableBlurUtils() : BlurUtils(resources, dumpController) {
        override fun supportsBlursOnWindows(): Boolean {
            return true
        }

        override fun createTransaction(): SurfaceControl.Transaction {
            return transaction
        }
    }
}
 No newline at end of file