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

Commit e026c7bf authored by Jacky Wang's avatar Jacky Wang
Browse files

[Catalyst] Allow specify order in hierarchy

A preference could have different orders on different screen. Hence, we
should specify order in screen hierarchy.

Bug: 332201912
Flag: EXEMPT framework
Test: N/A
Change-Id: I1488358a38e561b9516425c2b3b7f5ad70f7145a
parent 5add9d18
Loading
Loading
Loading
Loading
+35 −18
Original line number Diff line number Diff line
@@ -17,7 +17,15 @@
package com.android.settingslib.metadata

/** A node in preference hierarchy that is associated with [PreferenceMetadata]. */
open class PreferenceHierarchyNode internal constructor(val metadata: PreferenceMetadata)
open class PreferenceHierarchyNode internal constructor(val metadata: PreferenceMetadata) {
    /**
     * Preference order in the hierarchy.
     *
     * When a preference appears on different screens, different order values could be specified.
     */
    var order: Int? = null
        internal set
}

/**
 * Preference hierarchy describes the structure of preferences recursively.
@@ -30,9 +38,7 @@ class PreferenceHierarchy internal constructor(metadata: PreferenceMetadata) :
    private val children = mutableListOf<PreferenceHierarchyNode>()

    /** Adds a preference to the hierarchy. */
    operator fun PreferenceMetadata.unaryPlus() {
        children.add(PreferenceHierarchyNode(this))
    }
    operator fun PreferenceMetadata.unaryPlus() = +PreferenceHierarchyNode(this)

    /**
     * Adds preference screen with given key (as a placeholder) to the hierarchy.
@@ -45,13 +51,20 @@ class PreferenceHierarchy internal constructor(metadata: PreferenceMetadata) :
     *
     * @throws NullPointerException if screen is not registered to [PreferenceScreenRegistry]
     */
    operator fun String.unaryPlus() {
        children.add(PreferenceHierarchyNode(PreferenceScreenRegistry[this]!!))
    }
    operator fun String.unaryPlus() = +PreferenceHierarchyNode(PreferenceScreenRegistry[this]!!)

    operator fun PreferenceHierarchyNode.unaryPlus() = also { children.add(it) }

    /** Specifies preference order in the hierarchy. */
    infix fun PreferenceHierarchyNode.order(order: Int) = apply { this.order = order }

    /** Adds a preference to the hierarchy. */
    fun add(metadata: PreferenceMetadata) {
        children.add(PreferenceHierarchyNode(metadata))
    @JvmOverloads
    fun add(metadata: PreferenceMetadata, order: Int? = null) {
        PreferenceHierarchyNode(metadata).also {
            it.order = order
            children.add(it)
        }
    }

    /** Adds a preference to the hierarchy before a specific preference. */
@@ -72,8 +85,12 @@ class PreferenceHierarchy internal constructor(metadata: PreferenceMetadata) :
    operator fun PreferenceGroup.unaryPlus() = PreferenceHierarchy(this).also { children.add(it) }

    /** Adds a preference group and returns its preference hierarchy. */
    fun addGroup(metadata: PreferenceGroup): PreferenceHierarchy =
        PreferenceHierarchy(metadata).also { children.add(it) }
    @JvmOverloads
    fun addGroup(metadata: PreferenceGroup, order: Int? = null): PreferenceHierarchy =
        PreferenceHierarchy(metadata).also {
            this.order = order
            children.add(it)
        }

    /**
     * Adds preference screen with given key (as a placeholder) to the hierarchy.
@@ -91,7 +108,7 @@ class PreferenceHierarchy internal constructor(metadata: PreferenceMetadata) :
    }

    /** Extensions to add more preferences to the hierarchy. */
    operator fun plusAssign(init: PreferenceHierarchy.() -> Unit) = init(this)
    operator fun PreferenceHierarchy.plusAssign(init: PreferenceHierarchy.() -> Unit) = init(this)

    /** Traversals preference hierarchy and applies given action. */
    fun forEach(action: (PreferenceHierarchyNode) -> Unit) {
@@ -117,17 +134,17 @@ class PreferenceHierarchy internal constructor(metadata: PreferenceMetadata) :
        return null
    }

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

    private fun getAllPreferences(result: MutableList<PreferenceMetadata>) {
        result.add(metadata)
    private fun getAllPreferences(result: MutableList<PreferenceHierarchyNode>) {
        result.add(this)
        for (child in children) {
            if (child is PreferenceHierarchy) {
                child.getAllPreferences(result)
            } else {
                result.add(child.metadata)
                result.add(child)
            }
        }
    }
+1 −4
Original line number Diff line number Diff line
@@ -19,10 +19,10 @@ package com.android.settingslib.metadata
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.annotation.AnyThread
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.fragment.app.Fragment

/**
 * Interface provides preference metadata (title, summary, icon, etc.).
@@ -134,9 +134,6 @@ interface PreferenceMetadata {
    /** Returns preference intent. */
    fun intent(context: Context): Intent? = null

    /** Returns preference order. */
    fun order(context: Context): Int? = null

    /**
     * Returns the preference title.
     *
+0 −1
Original line number Diff line number Diff line
@@ -80,7 +80,6 @@ interface PreferenceBinding {
            preference.isVisible =
                (this as? PreferenceAvailabilityProvider)?.isAvailable(context) != false
            preference.isPersistent = isPersistent(context)
            metadata.order(context)?.let { preference.order = it }
            // PreferenceRegistry will notify dependency change, so we do not need to set
            // dependency here. This simplifies dependency management and avoid the
            // IllegalStateException when call Preference.setDependency
+7 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.settingslib.preference
import androidx.preference.Preference
import com.android.settingslib.metadata.MainSwitchPreference
import com.android.settingslib.metadata.PreferenceGroup
import com.android.settingslib.metadata.PreferenceHierarchyNode
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.SwitchPreference

@@ -34,9 +35,13 @@ interface PreferenceBindingFactory {
     */
    fun bind(
        preference: Preference,
        metadata: PreferenceMetadata,
        node: PreferenceHierarchyNode,
        preferenceBinding: PreferenceBinding? = null,
    ) = (preferenceBinding ?: getPreferenceBinding(metadata))?.bind(preference, metadata)
    ) {
        val binding = (preferenceBinding ?: getPreferenceBinding(node.metadata)) ?: return
        binding.bind(preference, node.metadata)
        node.order?.let { preference.order = it }
    }

    /** Returns the [PreferenceBinding] associated with the [PreferenceMetadata]. */
    fun getPreferenceBinding(metadata: PreferenceMetadata): PreferenceBinding?
+1 −1
Original line number Diff line number Diff line
@@ -129,7 +129,7 @@ open class PreferenceFragment :
    }

    protected fun getPreferenceKeysInHierarchy(): Set<String> =
        preferenceScreenBindingHelper?.getPreferences()?.map { it.key }?.toSet() ?: setOf()
        preferenceScreenBindingHelper?.getPreferences()?.map { it.metadata.key }?.toSet() ?: setOf()

    companion object {
        private const val TAG = "PreferenceFragment"
Loading