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

Commit 60dc72c8 authored by Zekan Qian's avatar Zekan Qian
Browse files

Add session source name.

Move PageLogger to separate file
Add session source name in navController and read in PageLogger.
Next: set different session source name in DebugActivity for demo.

Bug: 244122804
Test: unit-test & local build gallery
Change-Id: Ia6b745588314a1dd451cba539d2b09dc7005ec8e
parent d25aff02
Loading
Loading
Loading
Loading
+20 −48
Original line number Diff line number Diff line
@@ -16,21 +16,17 @@

package com.android.settingslib.spa.framework

import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.annotation.VisibleForTesting
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.core.view.WindowCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
@@ -39,12 +35,13 @@ import com.android.settingslib.spa.R
import com.android.settingslib.spa.framework.common.LogCategory
import com.android.settingslib.spa.framework.common.SettingsPage
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.common.SettingsPageProviderRepository
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.framework.common.createSettingsPage
import com.android.settingslib.spa.framework.compose.LocalNavController
import com.android.settingslib.spa.framework.compose.NavControllerWrapperImpl
import com.android.settingslib.spa.framework.compose.localNavController
import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.framework.util.PageEvent
import com.android.settingslib.spa.framework.util.navRoute

private const val TAG = "BrowseActivity"
@@ -77,12 +74,7 @@ open class BrowseActivity : ComponentActivity() {
        setContent {
            SettingsTheme {
                val sppRepository by spaEnvironment.pageProviderRepository
                BrowseContent(
                    allProviders = sppRepository.getAllProviders(),
                    initialDestination = intent?.getStringExtra(KEY_DESTINATION)
                        ?: sppRepository.getDefaultStartPage(),
                    initialEntryId = intent?.getStringExtra(KEY_HIGHLIGHT_ENTRY)
                )
                BrowseContent(sppRepository, intent)
            }
        }
    }
@@ -90,44 +82,18 @@ open class BrowseActivity : ComponentActivity() {
    companion object {
        const val KEY_DESTINATION = "spaActivityDestination"
        const val KEY_HIGHLIGHT_ENTRY = "highlightEntry"
        const val KEY_SESSION_SOURCE_NAME = "sessionSource"
    }
}

@VisibleForTesting
@Composable
fun BrowseContent(
    allProviders: Collection<SettingsPageProvider>,
    initialDestination: String,
    initialEntryId: String?
) {
fun BrowseContent(sppRepository: SettingsPageProviderRepository, initialIntent: Intent? = null) {
    val navController = rememberNavController()
    CompositionLocalProvider(navController.localNavController()) {
        val controller = LocalNavController.current as NavControllerWrapperImpl
        controller.NavContent(allProviders)
        controller.InitialDestination(initialDestination, initialEntryId)
    }
}

@Composable
private fun SettingsPageProvider.PageEvents(arguments: Bundle? = null) {
    val page = remember(arguments) { createSettingsPage(arguments) }
    val lifecycleOwner = LocalLifecycleOwner.current
    DisposableEffect(lifecycleOwner) {
        val observer = LifecycleEventObserver { _, event ->
            if (event == Lifecycle.Event.ON_START) {
                page.enterPage()
            } else if (event == Lifecycle.Event.ON_STOP) {
                page.leavePage()
            }
        }

        // Add the observer to the lifecycle
        lifecycleOwner.lifecycle.addObserver(observer)

        // When the effect leaves the Composition, remove the observer
        onDispose {
            lifecycleOwner.lifecycle.removeObserver(observer)
        }
        controller.NavContent(sppRepository.getAllProviders())
        controller.InitialDestination(initialIntent, sppRepository.getDefaultStartPage())
    }
}

@@ -144,7 +110,7 @@ private fun NavControllerWrapperImpl.NavContent(allProvider: Collection<Settings
                route = spp.name + spp.parameter.navRoute(),
                arguments = spp.parameter,
            ) { navBackStackEntry ->
                spp.PageEvents(navBackStackEntry.arguments)
                spp.PageEvent(navBackStackEntry.arguments)
                spp.Page(navBackStackEntry.arguments)
            }
        }
@@ -153,17 +119,23 @@ private fun NavControllerWrapperImpl.NavContent(allProvider: Collection<Settings

@Composable
private fun NavControllerWrapperImpl.InitialDestination(
    destination: String,
    highlightEntryId: String?
    initialIntent: Intent?,
    defaultDestination: String
) {
    val destinationNavigated = rememberSaveable { mutableStateOf(false) }
    if (destinationNavigated.value) return
    destinationNavigated.value = true

    if (destination.isEmpty()) return
    val initialDestination = initialIntent?.getStringExtra(BrowseActivity.KEY_DESTINATION)
        ?: defaultDestination
    if (initialDestination.isEmpty()) return
    val initialEntryId = initialIntent?.getStringExtra(BrowseActivity.KEY_HIGHLIGHT_ENTRY)
    val sessionSourceName = initialIntent?.getStringExtra(BrowseActivity.KEY_SESSION_SOURCE_NAME)

    LaunchedEffect(Unit) {
        highlightId = highlightEntryId
        navController.navigate(destination) {
        highlightId = initialEntryId
        sessionName = sessionSourceName
        navController.navigate(initialDestination) {
            popUpTo(navController.graph.findStartDestination().id) {
                inclusive = true
            }
+0 −18
Original line number Diff line number Diff line
@@ -95,24 +95,6 @@ data class SettingsPage(
        return false
    }

    fun enterPage() {
        SpaEnvironmentFactory.instance.logger.event(
            id,
            LogEvent.PAGE_ENTER,
            category = LogCategory.FRAMEWORK,
            details = displayName,
        )
    }

    fun leavePage() {
        SpaEnvironmentFactory.instance.logger.event(
            id,
            LogEvent.PAGE_LEAVE,
            category = LogCategory.FRAMEWORK,
            details = displayName,
        )
    }

    fun createBrowseIntent(entryId: String? = null): Intent? {
        val context = SpaEnvironmentFactory.instance.appContext
        val browseActivityClass = SpaEnvironmentFactory.instance.browseActivityClass
+9 −2
Original line number Diff line number Diff line
@@ -30,6 +30,9 @@ interface NavControllerWrapper {

    val highlightEntryId: String?
        get() = null

    val sessionSourceName: String?
        get() = null
}

@Composable
@@ -63,6 +66,7 @@ internal class NavControllerWrapperImpl(
    private val onBackPressedDispatcher: OnBackPressedDispatcher?,
) : NavControllerWrapper {
    var highlightId: String? = null
    var sessionName: String? = null

    override fun navigate(route: String) {
        navController.navigate(route)
@@ -74,4 +78,7 @@ internal class NavControllerWrapperImpl(

    override val highlightEntryId: String?
        get() = highlightId

    override val sessionSourceName: String?
        get() = sessionName
}
+0 −0

File moved.

+66 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.settingslib.spa.framework.util

import android.os.Bundle
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import com.android.settingslib.spa.framework.common.LogCategory
import com.android.settingslib.spa.framework.common.LogEvent
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.framework.common.createSettingsPage
import com.android.settingslib.spa.framework.compose.LocalNavController

@Composable
internal fun SettingsPageProvider.PageEvent(arguments: Bundle? = null) {
    val page = remember(arguments) { createSettingsPage(arguments) }
    val lifecycleOwner = LocalLifecycleOwner.current
    val navController = LocalNavController.current
    DisposableEffect(lifecycleOwner) {
        val observer = LifecycleEventObserver { _, event ->
            val spaLogger = SpaEnvironmentFactory.instance.logger
            if (event == Lifecycle.Event.ON_START) {
                spaLogger.event(
                    page.id,
                    LogEvent.PAGE_ENTER,
                    category = LogCategory.FRAMEWORK,
                    details = navController.sessionSourceName ?: page.displayName,
                )
            } else if (event == Lifecycle.Event.ON_STOP) {
                spaLogger.event(
                    page.id,
                    LogEvent.PAGE_LEAVE,
                    category = LogCategory.FRAMEWORK,
                    details = navController.sessionSourceName ?: page.displayName,
                )
            }
        }

        // Add the observer to the lifecycle
        lifecycleOwner.lifecycle.addObserver(observer)

        // When the effect leaves the Composition, remove the observer
        onDispose {
            lifecycleOwner.lifecycle.removeObserver(observer)
        }
    }
}
Loading