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

Commit 1bbab400 authored by Jacky Wang's avatar Jacky Wang
Browse files

[Catalyst] Create preference widget for placeholder

In hybrid mode, main switch bar preference does not appear in preference
screen but is added to the preference hierarchy.

Bug: 332201912
Flag: EXEMPT library
Test: manual
Change-Id: I3b5a51437be849e204914613b4dc971531c0b773
parent 0c46131c
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -166,10 +166,6 @@ class PreferenceHierarchy internal constructor(metadata: PreferenceMetadata) :
        }
        return null
    }

    /** Returns all the [PreferenceHierarchyNode]s appear in the hierarchy. */
    fun getAllPreferences(): List<PreferenceHierarchyNode> =
        mutableListOf<PreferenceHierarchyNode>().apply { forEachRecursively { add(it) } }
}

/**
+3 −0
Original line number Diff line number Diff line
@@ -108,6 +108,9 @@ interface PreferenceBinding {
    }
}

/** Interface indicates that a virtual [Preference] should be created for binding. */
interface PreferenceBindingPlaceholder

/** Abstract preference screen to provide preference hierarchy and binding factory. */
interface PreferenceScreenCreator : PreferenceScreenMetadata, PreferenceScreenProvider {

+36 −23
Original line number Diff line number Diff line
@@ -218,34 +218,47 @@ class PreferenceScreenBindingHelper(
            preferenceScreen: PreferenceScreen,
            preferenceBindingFactory: PreferenceBindingFactory,
            preferenceHierarchy: PreferenceHierarchy,
        ) =
            preferenceScreen.bindRecursively(
                preferenceBindingFactory,
                preferenceHierarchy.getAllPreferences().associateBy { it.metadata.key },
            )

        private fun PreferenceGroup.bindRecursively(
            preferenceBindingFactory: PreferenceBindingFactory,
            preferences: Map<String, PreferenceHierarchyNode>,
            storages: MutableMap<KeyValueStore, PreferenceDataStore> = mutableMapOf(),
        ) {
            preferences[key]?.let { preferenceBindingFactory.bind(this, it) }
            val preferences = mutableMapOf<String, PreferenceHierarchyNode>()
            preferenceHierarchy.forEachRecursively {
                val metadata = it.metadata
                preferences[metadata.key] = it
            }
            val storages = mutableMapOf<KeyValueStore, PreferenceDataStore>()

            fun Preference.setPreferenceDataStore(metadata: PreferenceMetadata) {
                (metadata as? PersistentPreference<*>)?.storage(context)?.let { storage ->
                    preferenceDataStore =
                        storages.getOrPut(storage) { PreferenceDataStoreAdapter(storage) }
                }
            }

            fun PreferenceGroup.bindRecursively() {
                preferences.remove(key)?.let { preferenceBindingFactory.bind(this, it) }
                val count = preferenceCount
                for (index in 0 until count) {
                    val preference = getPreference(index)
                    if (preference is PreferenceGroup) {
                    preference.bindRecursively(preferenceBindingFactory, preferences, storages)
                        preference.bindRecursively()
                    } else {
                    preferences[preference.key]?.let {
                        val metadata = it.metadata
                        (metadata as? PersistentPreference<*>)?.storage(context)?.let { storage ->
                            preference.preferenceDataStore =
                                storages.getOrPut(storage) { PreferenceDataStoreAdapter(storage) }
                        }
                        preferences.remove(preference.key)?.let {
                            preference.setPreferenceDataStore(it.metadata)
                            preferenceBindingFactory.bind(preference, it)
                        }
                    }
                }
            }

            preferenceScreen.bindRecursively()
            for (node in preferences.values) {
                val metadata = node.metadata
                val binding = preferenceBindingFactory.getPreferenceBinding(metadata)
                if (binding !is PreferenceBindingPlaceholder) continue
                val preference = binding.createWidget(preferenceScreen.context)
                preference.setPreferenceDataStore(metadata)
                preferenceBindingFactory.bind(preference, node, binding)
                preferenceScreen.addPreference(preference)
            }
        }
    }
}