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

Commit 02e79df1 authored by Chris Göllner's avatar Chris Göllner Committed by Android (Google) Code Review
Browse files

Merge changes I73ee8e68,I5da93401 into main

* changes:
  Introduce StatusBarWindowControllerStore
  Create DisplayWindowPropertiesRepository
parents cb3fe7f5 92f5c3cf
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@ import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.DisplayRepositoryImpl
import com.android.systemui.display.data.repository.DisplayScopeRepository
import com.android.systemui.display.data.repository.DisplayScopeRepositoryImpl
import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepositoryImpl
import com.android.systemui.display.data.repository.FocusedDisplayRepository
import com.android.systemui.display.data.repository.FocusedDisplayRepositoryImpl
import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor
@@ -58,6 +60,11 @@ interface DisplayModule {

    @Binds fun displayScopeRepository(impl: DisplayScopeRepositoryImpl): DisplayScopeRepository

    @Binds
    fun displayWindowPropertiesRepository(
        impl: DisplayWindowPropertiesRepositoryImpl
    ): DisplayWindowPropertiesRepository

    companion object {
        @Provides
        @SysUISingleton
@@ -72,5 +79,19 @@ interface DisplayModule {
                CoreStartable.NOP
            }
        }

        @Provides
        @SysUISingleton
        @IntoMap
        @ClassKey(DisplayWindowPropertiesRepository::class)
        fun displayWindowPropertiesRepoAsCoreStartable(
            repoLazy: Lazy<DisplayWindowPropertiesRepositoryImpl>
        ): CoreStartable {
            return if (StatusBarConnectedDisplays.isEnabled) {
                return repoLazy.get()
            } else {
                CoreStartable.NOP
            }
        }
    }
}
+115 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.data.repository

import android.annotation.SuppressLint
import android.content.Context
import android.view.Display
import android.view.WindowManager
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.display.shared.model.DisplayWindowProperties
import com.android.systemui.res.R
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.google.common.collect.HashBasedTable
import com.google.common.collect.Table
import java.io.PrintWriter
import javax.inject.Inject
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

/** Provides per display instances of [DisplayWindowProperties]. */
interface DisplayWindowPropertiesRepository {

    /**
     * Returns a [DisplayWindowProperties] instance for a given display id and window type.
     *
     * @throws IllegalArgumentException if no display with the given display id exists.
     */
    fun get(
        displayId: Int,
        @WindowManager.LayoutParams.WindowType windowType: Int,
    ): DisplayWindowProperties
}

@SysUISingleton
class DisplayWindowPropertiesRepositoryImpl
@Inject
constructor(
    @Background private val backgroundApplicationScope: CoroutineScope,
    private val globalContext: Context,
    private val globalWindowManager: WindowManager,
    private val displayRepository: DisplayRepository,
) : DisplayWindowPropertiesRepository, CoreStartable {

    init {
        StatusBarConnectedDisplays.assertInNewMode()
    }

    private val properties: Table<Int, Int, DisplayWindowProperties> = HashBasedTable.create()

    override fun get(
        displayId: Int,
        @WindowManager.LayoutParams.WindowType windowType: Int,
    ): DisplayWindowProperties {
        val display =
            displayRepository.getDisplay(displayId)
                ?: throw IllegalArgumentException("Display with id $displayId doesn't exist")
        return properties.get(displayId, windowType)
            ?: create(display, windowType).also { properties.put(displayId, windowType, it) }
    }

    override fun start() {
        backgroundApplicationScope.launch(
            CoroutineName("DisplayWindowPropertiesRepositoryImpl#start")
        ) {
            displayRepository.displayRemovalEvent.collect { removedDisplayId ->
                properties.row(removedDisplayId).clear()
            }
        }
    }

    private fun create(display: Display, windowType: Int): DisplayWindowProperties {
        val displayId = display.displayId
        return if (displayId == Display.DEFAULT_DISPLAY) {
            // For the default display, we can just reuse the global/application properties.
            // Creating a window context is expensive, therefore we avoid it.
            DisplayWindowProperties(
                displayId = displayId,
                windowType = windowType,
                context = globalContext,
                windowManager = globalWindowManager,
            )
        } else {
            val context = createWindowContext(display, windowType)
            @SuppressLint("NonInjectedService") // Need to manually get the service
            val windowManager = context.getSystemService(WindowManager::class.java) as WindowManager
            DisplayWindowProperties(displayId, windowType, context, windowManager)
        }
    }

    private fun createWindowContext(display: Display, windowType: Int): Context =
        globalContext.createWindowContext(display, windowType, /* options= */ null).also {
            it.setTheme(R.style.Theme_SystemUI)
        }

    override fun dump(pw: PrintWriter, args: Array<out String>) {
        pw.write("perDisplayContexts: $properties")
    }
}
+43 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.model

import android.content.Context
import android.view.WindowManager

/** Represents a display specific group of window related properties. */
data class DisplayWindowProperties(
    /** The id of the display associated with this instance. */
    val displayId: Int,
    /**
     * The window type that was used to create the [Context] in this instance, using
     * [Context.createWindowContext]. This is the window type that can be used when adding views to
     * the [WindowManager] associated with this instance.
     */
    @WindowManager.LayoutParams.WindowType val windowType: Int,
    /**
     * The display specific [Context] created using [Context.createWindowContext] with window type
     * associated with this instance.
     */
    val context: Context,

    /**
     * The display specific [WindowManager] instance to be used when adding windows of the type
     * associated with this instance.
     */
    val windowManager: WindowManager,
)
+41 −3
Original line number Diff line number Diff line
@@ -22,15 +22,20 @@ import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogBufferFactory
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.statusbar.data.StatusBarDataLayerModule
import com.android.systemui.statusbar.phone.LightBarController
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallLog
import com.android.systemui.statusbar.ui.SystemBarUtilsProxyImpl
import com.android.systemui.statusbar.window.MultiDisplayStatusBarWindowControllerStore
import com.android.systemui.statusbar.window.SingleDisplayStatusBarWindowControllerStore
import com.android.systemui.statusbar.window.StatusBarWindowController
import com.android.systemui.statusbar.window.StatusBarWindowControllerImpl
import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
import dagger.Binds
import dagger.Lazy
import dagger.Module
import dagger.Provides
import dagger.multibindings.ClassKey
@@ -62,18 +67,51 @@ abstract class StatusBarModule {
    @ClassKey(StatusBarSignalPolicy::class)
    abstract fun bindStatusBarSignalPolicy(impl: StatusBarSignalPolicy): CoreStartable

    @Binds
    @SysUISingleton
    abstract fun statusBarWindowControllerFactory(
        implFactory: StatusBarWindowControllerImpl.Factory
    ): StatusBarWindowController.Factory

    companion object {

        @Provides
        @SysUISingleton
        fun statusBarWindowController(
            context: Context?,
            viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager?,
        fun defaultStatusBarWindowController(
            context: Context,
            viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager,
            factory: StatusBarWindowControllerImpl.Factory,
        ): StatusBarWindowController {
            return factory.create(context, viewCaptureAwareWindowManager)
        }

        @Provides
        @SysUISingleton
        fun windowControllerStore(
            multiDisplayImplLazy: Lazy<MultiDisplayStatusBarWindowControllerStore>,
            singleDisplayImplLazy: Lazy<SingleDisplayStatusBarWindowControllerStore>,
        ): StatusBarWindowControllerStore {
            return if (StatusBarConnectedDisplays.isEnabled) {
                multiDisplayImplLazy.get()
            } else {
                singleDisplayImplLazy.get()
            }
        }

        @Provides
        @SysUISingleton
        @IntoMap
        @ClassKey(MultiDisplayStatusBarWindowControllerStore::class)
        fun multiDisplayControllerStoreAsCoreStartable(
            storeLazy: Lazy<MultiDisplayStatusBarWindowControllerStore>
        ): CoreStartable {
            return if (StatusBarConnectedDisplays.isEnabled) {
                storeLazy.get()
            } else {
                CoreStartable.NOP
            }
        }

        @Provides
        @SysUISingleton
        @OngoingCallLog
+9 −0
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

package com.android.systemui.statusbar.window

import android.content.Context
import android.view.View
import android.view.ViewGroup
import com.android.app.viewcapture.ViewCaptureAwareWindowManager
import com.android.systemui.animation.ActivityTransitionAnimator
import com.android.systemui.fragments.FragmentHostManager
import java.util.Optional
@@ -73,4 +75,11 @@ interface StatusBarWindowController {
     *   this#setForceStatusBarVisible} together and use some sort of ranking system instead.
     */
    fun setOngoingProcessRequiresStatusBarVisible(visible: Boolean)

    interface Factory {
        fun create(
            context: Context,
            viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager,
        ): StatusBarWindowController
    }
}
Loading