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