• 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.fragment.app.Fragment
24 import kotlinx.coroutines.flow.Flow
25 
26 /**
27  * Metadata of preference screen.
28  *
29  * For parameterized preference screen that relies on additional information (e.g. package name,
30  * language code) to build its content, the subclass must:
31  * - override [arguments] in constructor
32  * - add a static method `fun parameters(context: Context): List<Bundle>` (context is optional) to
33  *   provide all possible arguments
34  */
35 @AnyThread
36 interface PreferenceScreenMetadata : PreferenceMetadata {
37     /** Arguments to build the screen content. */
38     val arguments: Bundle?
39         get() = null
40 
41     /**
42      * The screen title resource, which precedes [getScreenTitle] if provided.
43      *
44      * By default, screen title is same with [title].
45      */
46     val screenTitle: Int
47         get() = title
48 
49     /** Returns dynamic screen title, use [screenTitle] whenever possible. */
getScreenTitlenull50     fun getScreenTitle(context: Context): CharSequence? = null
51 
52     /** Returns the fragment class to show the preference screen. */
53     fun fragmentClass(): Class<out Fragment>?
54 
55     /**
56      * Indicates if [getPreferenceHierarchy] returns a complete hierarchy of the preference screen.
57      *
58      * If `true`, the result of [getPreferenceHierarchy] will be used to inflate preference screen.
59      * Otherwise, it is an intermediate state called hybrid mode, preference hierarchy is
60      * represented by other ways (e.g. XML resource) and [PreferenceMetadata]s in
61      * [getPreferenceHierarchy] will only be used to bind UI widgets.
62      */
63     fun hasCompleteHierarchy(): Boolean = true
64 
65     /**
66      * Returns the hierarchy of preference screen.
67      *
68      * The implementation MUST include all preferences into the hierarchy regardless of the runtime
69      * conditions. DO NOT check any condition (except compile time flag) before adding a preference.
70      */
71     fun getPreferenceHierarchy(context: Context): PreferenceHierarchy
72 
73     /**
74      * Returns the [Intent] to show current preference screen.
75      *
76      * @param metadata the preference to locate when show the screen
77      */
78     fun getLaunchIntent(context: Context, metadata: PreferenceMetadata?): Intent? = null
79 }
80 
81 /**
82  * Factory of [PreferenceScreenMetadata].
83  *
84  * Annotation processor generates implementation of this interface based on
85  * [ProvidePreferenceScreen] when [ProvidePreferenceScreen.parameterized] is `false`.
86  */
87 fun interface PreferenceScreenMetadataFactory {
88 
89     /**
90      * Creates a new [PreferenceScreenMetadata].
91      *
92      * @param context application context to create the PreferenceScreenMetadata
93      */
94     fun create(context: Context): PreferenceScreenMetadata
95 }
96 
97 /**
98  * Parameterized factory of [PreferenceScreenMetadata].
99  *
100  * Annotation processor generates implementation of this interface based on
101  * [ProvidePreferenceScreen] when [ProvidePreferenceScreen.parameterized] is `true`.
102  */
103 interface PreferenceScreenMetadataParameterizedFactory : PreferenceScreenMetadataFactory {
createnull104     override fun create(context: Context) = create(context, Bundle.EMPTY)
105 
106     /**
107      * Creates a new [PreferenceScreenMetadata] with given arguments.
108      *
109      * @param context application context to create the PreferenceScreenMetadata
110      * @param args arguments to create the screen metadata, [Bundle.EMPTY] is reserved for the
111      *   default case when screen is migrated from normal to parameterized
112      */
113     fun create(context: Context, args: Bundle): PreferenceScreenMetadata
114 
115     /**
116      * Returns all possible arguments to create [PreferenceScreenMetadata].
117      *
118      * Note that [Bundle.EMPTY] is a special arguments reserved for backward compatibility when a
119      * preference screen was a normal screen but migrated to parameterized screen later:
120      * 1. Set [ProvidePreferenceScreen.parameterizedMigration] to `true`, so that the generated
121      *    [acceptEmptyArguments] will be `true`.
122      * 1. In the original [parameters] implementation, produce a [Bundle.EMPTY] for the default
123      *    case.
124      *
125      * Do not use [Bundle.EMPTY] for other purpose.
126      */
127     fun parameters(context: Context): Flow<Bundle>
128 
129     /**
130      * Returns true when the parameterized screen was a normal screen.
131      *
132      * The [PreferenceScreenMetadata] is expected to accept an empty arguments ([Bundle.EMPTY]) and
133      * take care of backward compatibility.
134      */
135     fun acceptEmptyArguments(): Boolean = false
136 }
137