• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settingslib.metadata
18 
19 import android.content.Context
20 import android.content.Intent
21 import android.os.Bundle
22 import androidx.annotation.AnyThread
23 import androidx.annotation.DrawableRes
24 import androidx.annotation.StringRes
25 
26 /**
27  * Interface provides preference metadata (title, summary, icon, etc.).
28  *
29  * Besides the existing APIs, subclass could integrate with following interface to provide more
30  * information:
31  * - [PreferenceTitleProvider]: provide dynamic title content
32  * - [PreferenceSummaryProvider]: provide dynamic summary content (e.g. based on preference value)
33  * - [PreferenceIconProvider]: provide dynamic icon content (e.g. based on flag)
34  * - [PreferenceAvailabilityProvider]: provide preference availability (e.g. based on flag)
35  * - [PreferenceLifecycleProvider]: provide the lifecycle callbacks and notify state change
36  *
37  * Notes:
38  * - UI framework support:
39  *     - This class does not involve any UI logic, it is the data layer.
40  *     - Subclass could integrate with datastore and UI widget to provide UI layer. For instance,
41  *       `PreferenceBinding` supports Jetpack Preference binding.
42  * - Datastore:
43  *     - Subclass should implement the [PersistentPreference] to note that current preference is
44  *       persistent in datastore.
45  *     - It is always recommended to support back up preference value changed by user. Typically,
46  *       the back up and restore happen within datastore, the [allowBackup] API is to mark if
47  *       current preference value should be backed up (backup allowed by default).
48  * - Preference indexing for search:
49  *     - Override [isIndexable] API to mark if preference is indexable (enabled by default).
50  *     - If [isIndexable] returns true, preference title and summary will be indexed with cache.
51  *       More indexing data could be provided through [keywords].
52  *     - Settings search will cache the preference title/summary/keywords for indexing. The cache is
53  *       invalidated when system locale changed, app upgraded, etc.
54  *     - Dynamic content is not suitable to be cached for indexing. Subclass that implements
55  *       [PreferenceTitleProvider] / [PreferenceSummaryProvider] will not have its title / summary
56  *       indexed.
57  */
58 @AnyThread
59 interface PreferenceMetadata {
60 
61     /** Preference key. */
62     val key: String
63 
64     /**
65      * Preference title resource id.
66      *
67      * Implement [PreferenceTitleProvider] if title is generated dynamically.
68      */
69     val title: Int
70         @StringRes get() = 0
71 
72     /**
73      * Preference summary resource id.
74      *
75      * Implement [PreferenceSummaryProvider] if summary is generated dynamically (e.g. summary is
76      * provided per preference value)
77      */
78     val summary: Int
79         @StringRes get() = 0
80 
81     /** Icon of the preference. */
82     val icon: Int
83         @DrawableRes get() = 0
84 
85     /** Additional keywords for indexing. */
86     val keywords: Int
87         @StringRes get() = 0
88 
89     /**
90      * Return the extras Bundle object associated with this preference.
91      *
92      * It is used to provide more *internal* information for metadata. External app is not expected
93      * to use this information as it could be changed in future. Consider [tags] for external usage.
94      */
extrasnull95     fun extras(context: Context): Bundle? = null
96 
97     /**
98      * Returns the tags associated with this preference.
99      *
100      * Unlike [extras], tags are exposed for external usage. The returned tag list must be constants
101      * and **append only**. Do not edit/delete existing tag strings as it can cause backward
102      * compatibility issue.
103      *
104      * Use cases:
105      * - identify a specific preference
106      * - identify a group of preferences related to network settings
107      */
108     fun tags(context: Context): Array<String> = arrayOf()
109 
110     /**
111      * Returns if preference is indexable, default value is `true`.
112      *
113      * Return `false` only when the preference is always unavailable on current device. If it is
114      * conditional available, override [PreferenceAvailabilityProvider].
115      */
116     fun isIndexable(context: Context): Boolean = true
117 
118     /**
119      * Returns if preference is enabled.
120      *
121      * UI framework normally does not allow user to interact with the preference widget when it is
122      * disabled.
123      */
124     fun isEnabled(context: Context): Boolean = true
125 
126     /** Returns the keys of depended preferences. */
127     fun dependencies(context: Context): Array<String> = arrayOf()
128 
129     /** Returns if the preference is persistent in datastore. */
130     fun isPersistent(context: Context): Boolean = false
131 
132     /**
133      * Returns if preference value backup is allowed (by default returns `true` if preference is
134      * persistent).
135      */
136     fun allowBackup(context: Context): Boolean = isPersistent(context)
137 
138     /** Returns preference intent. */
139     fun intent(context: Context): Intent? = null
140 }
141 
142 /** Metadata of preference group. */
143 @AnyThread interface PreferenceGroup : PreferenceMetadata
144 
145 /** Metadata of preference category. */
146 @AnyThread
147 open class PreferenceCategory(override val key: String, override val title: Int) : PreferenceGroup
148