Add SpaLogger.
Define SpaLogger interface.
Add SpaLogger in SpaEnvironment.
Add Page enter / leave event in BrowseActivity
Use SpaLogger in Gallery Pages for logging.
Bug: 244122804
Test: manual - build Gallery
Change-Id: Id1df1760a0ddbf13f6a10ef3ef42b28fd398542f
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt
index d154dc1..acb22da 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt
@@ -16,6 +16,7 @@
package com.android.settingslib.spa.gallery
+import com.android.settingslib.spa.framework.common.LocalLogger
import com.android.settingslib.spa.framework.common.SettingsPageProviderRepository
import com.android.settingslib.spa.framework.common.SpaEnvironment
import com.android.settingslib.spa.framework.common.createSettingsPage
@@ -75,4 +76,6 @@
override val browseActivityClass = GalleryMainActivity::class.java
override val entryProviderAuthorities = "com.android.spa.gallery.provider"
+
+ override val logger = LocalLogger()
}
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPageModel.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPageModel.kt
index 107d3f3..e5e3c67 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPageModel.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPageModel.kt
@@ -17,13 +17,13 @@
package com.android.settingslib.spa.gallery.page
import android.os.Bundle
-import android.util.Log
import androidx.compose.runtime.Composable
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavType
import androidx.navigation.navArgument
import com.android.settingslib.spa.framework.common.EntrySearchData
import com.android.settingslib.spa.framework.common.PageModel
+import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.compose.stateOf
import com.android.settingslib.spa.framework.util.getIntArg
@@ -32,6 +32,8 @@
import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
import com.android.settingslib.spa.widget.preference.PreferenceModel
+private const val TAG = "ArgumentPageModel"
+
// Defines all the resources for this page.
// In real Settings App, resources data is defined in xml, rather than SPP.
private const val PAGE_TITLE = "Sample page with arguments"
@@ -93,7 +95,9 @@
private var intParam: Int? = null
override fun initialize(arguments: Bundle?) {
- logMsg("init with args " + arguments.toString())
+ SpaEnvironmentFactory.instance.logger.message(
+ TAG, "Initialize with args " + arguments.toString()
+ )
this.arguments = arguments
stringParam = parameter.getStringArg(STRING_PARAM_NAME, arguments)
intParam = parameter.getIntArg(INT_PARAM_NAME, arguments)
@@ -135,7 +139,3 @@
}
}
}
-
-private fun logMsg(message: String) {
- Log.d("ArgumentPageModel", message)
-}
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePage.kt
index f19e9a3..a2a913f 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePage.kt
@@ -30,6 +30,7 @@
import com.android.settingslib.spa.framework.common.SettingsEntry
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
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.toState
import com.android.settingslib.spa.framework.theme.SettingsTheme
@@ -44,13 +45,14 @@
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.SIMPLE_PREFERENCE_KEYWORDS
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.SIMPLE_PREFERENCE_SUMMARY
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.SIMPLE_PREFERENCE_TITLE
-import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.logMsg
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.preference.SimplePreferenceMacro
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
import com.android.settingslib.spa.widget.ui.SettingsIcon
+private const val TAG = "PreferencePage"
+
object PreferencePageProvider : SettingsPageProvider {
// Defines all entry name in this page.
// Note that entry name would be used in log. DO NOT change it once it is set.
@@ -67,6 +69,7 @@
override val name = SettingsPageProviderEnum.PREFERENCE.name
override val displayName = SettingsPageProviderEnum.PREFERENCE.displayName
+ private val spaLogger = SpaEnvironmentFactory.instance.logger
private val owner = createSettingsPage()
private fun createEntry(entry: EntryEnum): SettingsEntryBuilder {
@@ -79,7 +82,7 @@
createEntry(EntryEnum.SIMPLE_PREFERENCE)
.setIsAllowSearch(true)
.setMacro {
- logMsg("create macro for ${EntryEnum.SIMPLE_PREFERENCE}")
+ spaLogger.message(TAG, "create macro for ${EntryEnum.SIMPLE_PREFERENCE}")
SimplePreferenceMacro(title = SIMPLE_PREFERENCE_TITLE)
}
.build()
@@ -88,7 +91,7 @@
createEntry(EntryEnum.SUMMARY_PREFERENCE)
.setIsAllowSearch(true)
.setMacro {
- logMsg("create macro for ${EntryEnum.SUMMARY_PREFERENCE}")
+ spaLogger.message(TAG, "create macro for ${EntryEnum.SUMMARY_PREFERENCE}")
SimplePreferenceMacro(
title = SIMPLE_PREFERENCE_TITLE,
summary = SIMPLE_PREFERENCE_SUMMARY,
@@ -102,7 +105,7 @@
createEntry(EntryEnum.DISABLED_PREFERENCE)
.setIsAllowSearch(true)
.setMacro {
- logMsg("create macro for ${EntryEnum.DISABLED_PREFERENCE}")
+ spaLogger.message(TAG, "create macro for ${EntryEnum.DISABLED_PREFERENCE}")
SimplePreferenceMacro(
title = DISABLE_PREFERENCE_TITLE,
summary = DISABLE_PREFERENCE_SUMMARY,
@@ -188,7 +191,7 @@
return SettingsEntryBuilder.createInject(owner = owner)
.setIsAllowSearch(true)
.setMacro {
- logMsg("create macro for INJECT entry")
+ spaLogger.message(TAG, "create macro for INJECT entry")
SimplePreferenceMacro(
title = PAGE_TITLE,
clickRoute = SettingsPageProviderEnum.PREFERENCE.name
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageModel.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageModel.kt
index 1188e1e..1e64b2e 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageModel.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageModel.kt
@@ -17,7 +17,6 @@
package com.android.settingslib.spa.gallery.preference
import android.os.Bundle
-import android.util.Log
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
@@ -27,11 +26,14 @@
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel
import com.android.settingslib.spa.framework.common.PageModel
+import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
+private const val TAG = "PreferencePageModel"
+
class PreferencePageModel : PageModel() {
companion object {
// Defines all the resources for this page.
@@ -53,12 +55,10 @@
pageModel.initOnce()
return pageModel
}
-
- fun logMsg(message: String) {
- Log.d("PreferencePageModel", message)
- }
}
+ private val spaLogger = SpaEnvironmentFactory.instance.logger
+
private val asyncSummary = mutableStateOf(" ")
private val manualUpdater = mutableStateOf(0)
@@ -67,26 +67,25 @@
private var tick = 0
private var updateJob: Job? = null
override fun onActive() {
- logMsg("autoUpdater.active")
+ spaLogger.message(TAG, "autoUpdater.active")
updateJob = viewModelScope.launch(Dispatchers.IO) {
while (true) {
delay(1000L)
tick++
- logMsg("autoUpdater.value $tick")
+ spaLogger.message(TAG, "autoUpdater.value $tick")
postValue(tick.toString())
}
}
}
override fun onInactive() {
- logMsg("autoUpdater.inactive")
+ spaLogger.message(TAG, "autoUpdater.inactive")
updateJob?.cancel()
}
}
override fun initialize(arguments: Bundle?) {
- logMsg("init with args " + arguments.toString())
-
+ spaLogger.message(TAG, "initialize with args " + arguments.toString())
viewModelScope.launch(Dispatchers.IO) {
delay(2000L)
asyncSummary.value = ASYNC_PREFERENCE_SUMMARY
@@ -94,22 +93,22 @@
}
fun getAsyncSummary(): State<String> {
- logMsg("getAsyncSummary")
+ spaLogger.message(TAG, "getAsyncSummary")
return asyncSummary
}
fun getManualUpdaterSummary(): State<String> {
- logMsg("getManualUpdaterSummary")
+ spaLogger.message(TAG, "getManualUpdaterSummary")
return derivedStateOf { manualUpdater.value.toString() }
}
fun manualUpdaterOnClick() {
- logMsg("manualUpdaterOnClick")
+ spaLogger.message(TAG, "manualUpdaterOnClick")
manualUpdater.value = manualUpdater.value + 1
}
fun getAutoUpdaterSummary(): LiveData<String> {
- logMsg("getAutoUpdaterSummary")
+ spaLogger.message(TAG, "getAutoUpdaterSummary")
return autoUpdater
}
}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
index d87c31b..f9d2dbc 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
@@ -17,20 +17,25 @@
package com.android.settingslib.spa.framework
import android.os.Bundle
-import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
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.saveable.rememberSaveable
+import androidx.compose.ui.platform.LocalLifecycleOwner
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleEventObserver
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.android.settingslib.spa.R
+import com.android.settingslib.spa.framework.common.LogCategory
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
@@ -56,7 +61,7 @@
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.Theme_SpaLib_DayNight)
super.onCreate(savedInstanceState)
- Log.d(TAG, "onCreate")
+ spaEnvironment.logger.message(TAG, "onCreate", category = LogCategory.FRAMEWORK)
setContent {
SettingsTheme {
@@ -72,11 +77,43 @@
CompositionLocalProvider(navController.localNavController()) {
NavHost(navController, NULL_PAGE_NAME) {
composable(NULL_PAGE_NAME) {}
- for (page in sppRepository.getAllProviders()) {
+ for (spp in sppRepository.getAllProviders()) {
composable(
- route = page.name + page.parameter.navRoute(),
- arguments = page.parameter,
- ) { navBackStackEntry -> page.Page(navBackStackEntry.arguments) }
+ route = spp.name + spp.parameter.navRoute(),
+ arguments = spp.parameter,
+ ) { navBackStackEntry ->
+ val lifecycleOwner = LocalLifecycleOwner.current
+ val spaLogger = spaEnvironment.logger
+ val sp = spp.createSettingsPage(arguments = navBackStackEntry.arguments)
+
+ DisposableEffect(lifecycleOwner) {
+ val observer = LifecycleEventObserver { _, event ->
+ if (event == Lifecycle.Event.ON_START) {
+ spaLogger.event(
+ sp.id,
+ "enter page ${sp.formatDisplayTitle()}",
+ category = LogCategory.FRAMEWORK
+ )
+ } else if (event == Lifecycle.Event.ON_STOP) {
+ spaLogger.event(
+ sp.id,
+ "leave page ${sp.formatDisplayTitle()}",
+ category = LogCategory.FRAMEWORK
+ )
+ }
+ }
+
+ // Add the observer to the lifecycle
+ lifecycleOwner.lifecycle.addObserver(observer)
+
+ // When the effect leaves the Composition, remove the observer
+ onDispose {
+ lifecycleOwner.lifecycle.removeObserver(observer)
+ }
+ }
+
+ spp.Page(navBackStackEntry.arguments)
+ }
}
}
InitialDestinationNavigator()
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/DebugActivity.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/DebugActivity.kt
index b28da06..6f96818 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/DebugActivity.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/DebugActivity.kt
@@ -35,6 +35,7 @@
import com.android.settingslib.spa.R
import com.android.settingslib.spa.framework.BrowseActivity.Companion.KEY_DESTINATION
import com.android.settingslib.spa.framework.BrowseActivity.Companion.KEY_HIGHLIGHT_ENTRY
+import com.android.settingslib.spa.framework.common.LogCategory
import com.android.settingslib.spa.framework.common.SettingsEntry
import com.android.settingslib.spa.framework.common.SettingsPage
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
@@ -69,7 +70,7 @@
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.Theme_SpaLib_DayNight)
super.onCreate(savedInstanceState)
- Log.d(TAG, "onCreate")
+ spaEnvironment.logger.message(TAG, "onCreate", category = LogCategory.FRAMEWORK)
setContent {
SettingsTheme {
@@ -94,7 +95,7 @@
cursor.getBoolean(query, EntryProvider.ColumnEnum.HAS_RUNTIME_PARAM)
val message = "Page Info: $route ($entryCount) " +
(if (hasRuntimeParam) "with" else "no") + "-runtime-params"
- Log.d(TAG, message)
+ spaEnvironment.logger.message(TAG, message, category = LogCategory.FRAMEWORK)
}
}
} catch (e: Exception) {
@@ -229,7 +230,9 @@
putExtra(KEY_DESTINATION, route)
}
return {
- Log.d(TAG, "OpenPage: $route")
+ spaEnvironment.logger.message(
+ TAG, "OpenPage: $route", category = LogCategory.FRAMEWORK
+ )
context.startActivity(intent)
}
}
@@ -244,7 +247,9 @@
putExtra(KEY_HIGHLIGHT_ENTRY, entry.id)
}
return {
- Log.d(TAG, "OpenEntry: $route")
+ spaEnvironment.logger.message(
+ TAG, "OpenEntry: $route", category = LogCategory.FRAMEWORK
+ )
context.startActivity(intent)
}
}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaEnvironment.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaEnvironment.kt
index f762f6e..e0835ea 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaEnvironment.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaEnvironment.kt
@@ -48,5 +48,7 @@
open val entryProviderAuthorities: String? = null
+ open val logger: SpaLogger = object : SpaLogger {}
+
// TODO: add other environment setup here.
}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaLogger.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaLogger.kt
new file mode 100644
index 0000000..5efedec
--- /dev/null
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaLogger.kt
@@ -0,0 +1,52 @@
+/*
+ * 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.common
+
+import android.util.Log
+
+// Defines the category of the log, for quick filter
+enum class LogCategory {
+ // The default category, for logs from Pages & their Models.
+ DEFAULT,
+
+ // For logs from Spa Framework, such as BrowseActivity, EntryProvider
+ FRAMEWORK,
+
+ // For logs from Spa UI components, such as Widgets, Scaffold
+ VIEW,
+}
+
+/**
+ * The interface of logger in Spa
+ */
+interface SpaLogger {
+ // log a message, usually for debug purpose.
+ fun message(tag: String, msg: String, category: LogCategory = LogCategory.DEFAULT) {}
+
+ // log a user event.
+ fun event(id: String, event: String, category: LogCategory = LogCategory.DEFAULT) {}
+}
+
+class LocalLogger : SpaLogger {
+ override fun message(tag: String, msg: String, category: LogCategory) {
+ Log.d("SpaMsg-$category", "[$tag] $msg")
+ }
+
+ override fun event(id: String, event: String, category: LogCategory) {
+ Log.d("SpaEvent-$category", "[$id] $event")
+ }
+}
\ No newline at end of file