[PreferenceGraph] Introduce PreferenceScreenProvider
Bug: 332201912
Test: N/A
Change-Id: I6a67fa1058e974bcc857e59a6b3bfae94b5dcac2
diff --git a/packages/SettingsLib/Graph/Android.bp b/packages/SettingsLib/Graph/Android.bp
new file mode 100644
index 0000000..e2ed1e4
--- /dev/null
+++ b/packages/SettingsLib/Graph/Android.bp
@@ -0,0 +1,21 @@
+package {
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+filegroup {
+ name: "SettingsLibGraph-srcs",
+ srcs: ["src/**/*"],
+}
+
+android_library {
+ name: "SettingsLibGraph",
+ defaults: [
+ "SettingsLintDefaults",
+ ],
+ srcs: [":SettingsLibGraph-srcs"],
+ static_libs: [
+ "androidx.annotation_annotation",
+ "androidx.preference_preference",
+ ],
+ kotlincflags: ["-Xjvm-default=all"],
+}
diff --git a/packages/SettingsLib/Graph/AndroidManifest.xml b/packages/SettingsLib/Graph/AndroidManifest.xml
new file mode 100644
index 0000000..93acb35
--- /dev/null
+++ b/packages/SettingsLib/Graph/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.settingslib.graph">
+
+ <uses-sdk android:minSdkVersion="21" />
+</manifest>
diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceScreenManager.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceScreenManager.kt
new file mode 100644
index 0000000..9231f40
--- /dev/null
+++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceScreenManager.kt
@@ -0,0 +1,70 @@
+package com.android.settingslib.graph
+
+import androidx.annotation.StringRes
+import androidx.annotation.XmlRes
+import androidx.preference.Preference
+import androidx.preference.PreferenceManager
+import androidx.preference.PreferenceScreen
+
+/** Manager to create and initialize preference screen. */
+class PreferenceScreenManager(private val preferenceManager: PreferenceManager) {
+ private val context = preferenceManager.context
+ // the map will preserve order
+ private val updaters = mutableMapOf<String, PreferenceUpdater>()
+ private val screenUpdaters = mutableListOf<PreferenceScreenUpdater>()
+
+ /** Creates an empty [PreferenceScreen]. */
+ fun createPreferenceScreen(): PreferenceScreen =
+ preferenceManager.createPreferenceScreen(context)
+
+ /** Creates [PreferenceScreen] from resource. */
+ fun createPreferenceScreen(@XmlRes xmlRes: Int): PreferenceScreen =
+ preferenceManager.inflateFromResource(context, xmlRes, null)
+
+ /** Adds updater for given preference. */
+ fun addPreferenceUpdater(@StringRes key: Int, updater: PreferenceUpdater) =
+ addPreferenceUpdater(context.getString(key), updater)
+
+ /** Adds updater for given preference. */
+ fun addPreferenceUpdater(
+ key: String,
+ updater: PreferenceUpdater,
+ ): PreferenceScreenManager {
+ updaters.put(key, updater)?.let { if (it != updater) throw IllegalArgumentException() }
+ return this
+ }
+
+ /** Adds updater for preference screen. */
+ fun addPreferenceScreenUpdater(updater: PreferenceScreenUpdater): PreferenceScreenManager {
+ screenUpdaters.add(updater)
+ return this
+ }
+
+ /** Adds a list of updaters for preference screen. */
+ fun addPreferenceScreenUpdater(
+ vararg updaters: PreferenceScreenUpdater,
+ ): PreferenceScreenManager {
+ screenUpdaters.addAll(updaters)
+ return this
+ }
+
+ /** Updates preference screen with registered updaters. */
+ fun updatePreferenceScreen(preferenceScreen: PreferenceScreen) {
+ for ((key, updater) in updaters) {
+ preferenceScreen.findPreference<Preference>(key)?.let { updater.updatePreference(it) }
+ }
+ for (updater in screenUpdaters) {
+ updater.updatePreferenceScreen(preferenceScreen)
+ }
+ }
+}
+
+/** Updater of [Preference]. */
+interface PreferenceUpdater {
+ fun updatePreference(preference: Preference)
+}
+
+/** Updater of [PreferenceScreen]. */
+interface PreferenceScreenUpdater {
+ fun updatePreferenceScreen(preferenceScreen: PreferenceScreen)
+}
diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceScreenProvider.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceScreenProvider.kt
new file mode 100644
index 0000000..9e4c1f6
--- /dev/null
+++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceScreenProvider.kt
@@ -0,0 +1,26 @@
+package com.android.settingslib.graph
+
+import android.content.Context
+import androidx.preference.PreferenceScreen
+
+/**
+ * Interface to provide [PreferenceScreen].
+ *
+ * It is expected to be implemented by Activity/Fragment and the implementation needs to use
+ * [Context] APIs (e.g. `getContext()`, `getActivity()`) with caution: preference screen creation
+ * could happen in background service, where the Activity/Fragment lifecycle callbacks (`onCreate`,
+ * `onDestroy`, etc.) are not invoked.
+ */
+interface PreferenceScreenProvider {
+
+ /**
+ * Creates [PreferenceScreen].
+ *
+ * Preference screen creation could happen in background service. The implementation MUST use
+ * given [context] instead of APIs like `getContext()`, `getActivity()`, etc.
+ */
+ fun createPreferenceScreen(
+ context: Context,
+ preferenceScreenManager: PreferenceScreenManager,
+ ): PreferenceScreen?
+}