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

Commit 48710b2c authored by Jordan Demeulenaere's avatar Jordan Demeulenaere Committed by Automerger Merge Worker
Browse files

Merge changes from topics "people-space-benchmark",...

Merge changes from topics "people-space-benchmark", "people-space-jank-benchmark", "sysui-compose-initializer" into tm-qpr-dev am: 220397f1

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20803134



Change-Id: Ib9291cf05d7342f62b3e90de295a51022fc51cb5
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents b125f95c 220397f1
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -271,6 +271,7 @@ android_library {
        "LowLightDreamLib",
        "LowLightDreamLib",
        "motion_tool_lib",
        "motion_tool_lib",
        "androidx.core_core-animation-testing-nodeps",
        "androidx.core_core-animation-testing-nodeps",
        "androidx.compose.ui_ui",
    ],
    ],
}
}


+17 −1
Original line number Original line Diff line number Diff line
@@ -17,13 +17,21 @@


package com.android.systemui.compose
package com.android.systemui.compose


import android.content.Context
import android.view.View
import androidx.activity.ComponentActivity
import androidx.activity.ComponentActivity
import androidx.lifecycle.LifecycleOwner
import com.android.systemui.people.ui.viewmodel.PeopleViewModel
import com.android.systemui.people.ui.viewmodel.PeopleViewModel
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel


/** The Compose facade, when Compose is *not* available. */
/** The Compose facade, when Compose is *not* available. */
object ComposeFacade : BaseComposeFacade {
object ComposeFacade : BaseComposeFacade {
    override fun isComposeAvailable(): Boolean = false
    override fun isComposeAvailable(): Boolean = false


    override fun composeInitializer(): ComposeInitializer {
        throwComposeUnavailableError()
    }

    override fun setPeopleSpaceActivityContent(
    override fun setPeopleSpaceActivityContent(
        activity: ComponentActivity,
        activity: ComponentActivity,
        viewModel: PeopleViewModel,
        viewModel: PeopleViewModel,
@@ -32,7 +40,15 @@ object ComposeFacade : BaseComposeFacade {
        throwComposeUnavailableError()
        throwComposeUnavailableError()
    }
    }


    private fun throwComposeUnavailableError() {
    override fun createFooterActionsView(
        context: Context,
        viewModel: FooterActionsViewModel,
        qsVisibilityLifecycleOwner: LifecycleOwner
    ): View {
        throwComposeUnavailableError()
    }

    private fun throwComposeUnavailableError(): Nothing {
        error(
        error(
            "Compose is not available. Make sure to check isComposeAvailable() before calling any" +
            "Compose is not available. Make sure to check isComposeAvailable() before calling any" +
                " other function on ComposeFacade."
                " other function on ComposeFacade."
+18 −0
Original line number Original line Diff line number Diff line
@@ -16,16 +16,24 @@


package com.android.systemui.compose
package com.android.systemui.compose


import android.content.Context
import android.view.View
import androidx.activity.ComponentActivity
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.compose.setContent
import androidx.compose.ui.platform.ComposeView
import androidx.lifecycle.LifecycleOwner
import com.android.compose.theme.PlatformTheme
import com.android.compose.theme.PlatformTheme
import com.android.systemui.people.ui.compose.PeopleScreen
import com.android.systemui.people.ui.compose.PeopleScreen
import com.android.systemui.people.ui.viewmodel.PeopleViewModel
import com.android.systemui.people.ui.viewmodel.PeopleViewModel
import com.android.systemui.qs.footer.ui.compose.FooterActions
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel


/** The Compose facade, when Compose is available. */
/** The Compose facade, when Compose is available. */
object ComposeFacade : BaseComposeFacade {
object ComposeFacade : BaseComposeFacade {
    override fun isComposeAvailable(): Boolean = true
    override fun isComposeAvailable(): Boolean = true


    override fun composeInitializer(): ComposeInitializer = ComposeInitializerImpl

    override fun setPeopleSpaceActivityContent(
    override fun setPeopleSpaceActivityContent(
        activity: ComponentActivity,
        activity: ComponentActivity,
        viewModel: PeopleViewModel,
        viewModel: PeopleViewModel,
@@ -33,4 +41,14 @@ object ComposeFacade : BaseComposeFacade {
    ) {
    ) {
        activity.setContent { PlatformTheme { PeopleScreen(viewModel, onResult) } }
        activity.setContent { PlatformTheme { PeopleScreen(viewModel, onResult) } }
    }
    }

    override fun createFooterActionsView(
        context: Context,
        viewModel: FooterActionsViewModel,
        qsVisibilityLifecycleOwner: LifecycleOwner,
    ): View {
        return ComposeView(context).apply {
            setContent { PlatformTheme { FooterActions(viewModel, qsVisibilityLifecycleOwner) } }
        }
    }
}
}
+78 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2023 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.compose

import android.view.View
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewTreeLifecycleOwner
import androidx.savedstate.SavedStateRegistry
import androidx.savedstate.SavedStateRegistryController
import androidx.savedstate.SavedStateRegistryOwner
import com.android.compose.animation.ViewTreeSavedStateRegistryOwner
import com.android.systemui.lifecycle.ViewLifecycleOwner

internal object ComposeInitializerImpl : ComposeInitializer {
    override fun onAttachedToWindow(root: View) {
        if (ViewTreeLifecycleOwner.get(root) != null) {
            error("root $root already has a LifecycleOwner")
        }

        val parent = root.parent
        if (parent is View && parent.id != android.R.id.content) {
            error(
                "ComposeInitializer.onAttachedToWindow(View) must be called on the content child." +
                    "Outside of activities and dialogs, this is usually the top-most View of a " +
                    "window."
            )
        }

        // The lifecycle owner, which is STARTED when [root] is visible and RESUMED when [root] is
        // both visible and focused.
        val lifecycleOwner = ViewLifecycleOwner(root)

        // We create a trivial implementation of [SavedStateRegistryOwner] that does not do any save
        // or restore because SystemUI process is always running and top-level windows using this
        // initializer are created once, when the process is started.
        val savedStateRegistryOwner =
            object : SavedStateRegistryOwner {
                private val savedStateRegistry =
                    SavedStateRegistryController.create(this).apply { performRestore(null) }

                override fun getLifecycle(): Lifecycle = lifecycleOwner.lifecycle

                override fun getSavedStateRegistry(): SavedStateRegistry {
                    return savedStateRegistry.savedStateRegistry
                }
            }

        // We must call [ViewLifecycleOwner.onCreate] after creating the [SavedStateRegistryOwner]
        // because `onCreate` might move the lifecycle state to STARTED which will make
        // [SavedStateRegistryController.performRestore] throw.
        lifecycleOwner.onCreate()

        // Set the owners on the root. They will be reused by any ComposeView inside the root
        // hierarchy.
        ViewTreeLifecycleOwner.set(root, lifecycleOwner)
        ViewTreeSavedStateRegistryOwner.set(root, savedStateRegistryOwner)
    }

    override fun onDetachedFromWindow(root: View) {
        (ViewTreeLifecycleOwner.get(root) as ViewLifecycleOwner).onDestroy()
        ViewTreeLifecycleOwner.set(root, null)
        ViewTreeSavedStateRegistryOwner.set(root, null)
    }
}
+32 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2023 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.compose.modifiers

import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId

/**
 * Set a test tag on this node so that it is associated with [resId]. This node will then be
 * accessible by integration tests using `sysuiResSelector(resId)`.
 */
@OptIn(ExperimentalComposeUiApi::class)
fun Modifier.sysuiResTag(resId: String): Modifier {
    return this.semantics { testTagsAsResourceId = true }.testTag("com.android.systemui:id/$resId")
}
Loading