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

Commit 9139b906 authored by Steven Ng's avatar Steven Ng
Browse files

Catch DisplayNotFoundException in DisplayComponentInstanceProvider setUpInstance, destroyInstance

Problem:
A race condition from quickly toggling a display can invalidate its `android.view.Display` object, causing DisplayComponentInstanceProvider setUpInstance, destroyInstance to fail because they depend on a valid `Display` reference.

Flag: EXEMPT small bug fix
Test: atest CtsMediaProjectionTestCases:MediaProjectionTest
Bug: 441940469
Change-Id: I5aa49867ee15717954c12f33bae09936fb0dcb10
parent f0f7b0fc
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import com.android.systemui.display.data.repository.DisplayStateRepository
import com.android.systemui.display.data.repository.DisplayStateRepositoryImpl
import com.android.systemui.display.domain.interactor.DisplayStateInteractor
import com.android.systemui.display.domain.interactor.DisplayStateInteractorImpl
import com.android.systemui.display.shared.DisplayNotFoundException
import com.android.systemui.plugins.DarkIconDispatcher
import com.android.systemui.statusbar.dagger.PerDisplayStatusBarModule
import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl
@@ -111,7 +112,7 @@ interface PerDisplaySystemUIModule {
            displayRepository: DisplayRepository,
        ): Display {
            return displayRepository.getDisplay(displayId)
                ?: error("Couldn't get the display with id=$displayId")
                ?: throw DisplayNotFoundException("Couldn't get the display with id=$displayId")
        }

        @Provides
+17 −8
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.app.tracing.traceSection
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.display.dagger.SystemUIDisplaySubcomponent
import com.android.systemui.display.flags.DisplayComponentRepositoryFlag.isEagerInitializationEnabled
import com.android.systemui.display.shared.DisplayNotFoundException
import dagger.Module
import dagger.Provides
import javax.inject.Inject
@@ -54,19 +55,27 @@ constructor(private val componentFactory: SystemUIDisplaySubcomponent.Factory) :
        traceSection("Destroying a display component instance") {
            instance.displayCoroutineScope.cancel("Cancelling scope associated to the display.")
        }
        try {
            instance.lifecycleListeners.forEachTraced(
                "Notifying listeners of a display component destruction"
            ) {
                it.stop()
            }
        } catch (exception: DisplayNotFoundException) {
            Log.e(TAG, "Display no longer exists. Can't destroyInstance", exception)
        }
    }

    override fun setupInstance(instance: SystemUIDisplaySubcomponent) {
        try {
            instance.lifecycleListeners.forEachTraced(
                "Notifying listeners of a display component creation"
            ) {
                it.start()
            }
        } catch (exception: DisplayNotFoundException) {
            Log.e(TAG, "Display no longer exists. Can't setupInstance", exception)
        }
    }

    companion object {
+20 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.display.shared

/** A runtime exception thrown when a [android.view.Display] can't be found. */
class DisplayNotFoundException(message: String) : IllegalStateException(message)