1 /* 2 * Copyright (C) 2023 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.spa.framework.common 18 19 import android.os.Bundle 20 import androidx.compose.runtime.remember 21 import com.android.settingslib.spa.framework.util.genEntryId 22 23 private const val INJECT_ENTRY_LABEL = "INJECT" 24 private const val ROOT_ENTRY_LABEL = "ROOT" 25 26 /** 27 * The helper to build a Settings Entry instance. 28 */ 29 class SettingsEntryBuilder(private val name: String, private val owner: SettingsPage) { 30 private var label = name 31 private var fromPage: SettingsPage? = null 32 private var toPage: SettingsPage? = null 33 34 // Attributes 35 private var isAllowSearch: Boolean = false 36 private var isSearchDataDynamic: Boolean = false 37 private var hasMutableStatus: Boolean = false 38 39 // Functions <lambda>null40 private var uiLayoutFn: UiLayerRenderer = { } <lambda>null41 private var statusDataFn: StatusDataGetter = { null } <lambda>null42 private var searchDataFn: SearchDataGetter = { null } 43 buildnull44 fun build(): SettingsEntry { 45 val page = fromPage ?: owner 46 val isEnabled = page.isEnabled() 47 return SettingsEntry( 48 id = genEntryId(name, owner, fromPage, toPage), 49 name = name, 50 owner = owner, 51 label = label, 52 53 // linking data 54 fromPage = fromPage, 55 toPage = toPage, 56 57 // attributes 58 isAllowSearch = isEnabled && isAllowSearch, 59 isSearchDataDynamic = isSearchDataDynamic, 60 hasMutableStatus = hasMutableStatus, 61 62 // functions 63 statusDataImpl = statusDataFn, 64 searchDataImpl = searchDataFn, 65 uiLayoutImpl = uiLayoutFn, 66 ) 67 } 68 setLabelnull69 fun setLabel(label: String): SettingsEntryBuilder { 70 this.label = label 71 return this 72 } 73 setLinknull74 fun setLink( 75 fromPage: SettingsPage? = null, 76 toPage: SettingsPage? = null 77 ): SettingsEntryBuilder { 78 if (fromPage != null) this.fromPage = fromPage 79 if (toPage != null) this.toPage = toPage 80 return this 81 } 82 setIsSearchDataDynamicnull83 fun setIsSearchDataDynamic(isDynamic: Boolean): SettingsEntryBuilder { 84 this.isSearchDataDynamic = isDynamic 85 return this 86 } 87 setHasMutableStatusnull88 fun setHasMutableStatus(hasMutableStatus: Boolean): SettingsEntryBuilder { 89 this.hasMutableStatus = hasMutableStatus 90 return this 91 } 92 setMacronull93 fun setMacro(fn: (arguments: Bundle?) -> EntryMacro): SettingsEntryBuilder { 94 setStatusDataFn { fn(it).getStatusData() } 95 setSearchDataFn { fn(it).getSearchData() } 96 setUiLayoutFn { 97 val macro = remember { fn(it) } 98 macro.UiLayout() 99 } 100 return this 101 } 102 setStatusDataFnnull103 fun setStatusDataFn(fn: StatusDataGetter): SettingsEntryBuilder { 104 this.statusDataFn = fn 105 return this 106 } 107 setSearchDataFnnull108 fun setSearchDataFn(fn: SearchDataGetter): SettingsEntryBuilder { 109 this.searchDataFn = fn 110 this.isAllowSearch = true 111 return this 112 } 113 clearSearchDataFnnull114 fun clearSearchDataFn(): SettingsEntryBuilder { 115 this.searchDataFn = { null } 116 this.isAllowSearch = false 117 return this 118 } 119 setUiLayoutFnnull120 fun setUiLayoutFn(fn: UiLayerRenderer): SettingsEntryBuilder { 121 this.uiLayoutFn = fn 122 return this 123 } 124 125 companion object { createnull126 fun create(entryName: String, owner: SettingsPage): SettingsEntryBuilder { 127 return SettingsEntryBuilder(entryName, owner) 128 } 129 createLinkFromnull130 fun createLinkFrom(entryName: String, owner: SettingsPage): SettingsEntryBuilder { 131 return create(entryName, owner).setLink(fromPage = owner) 132 } 133 createLinkTonull134 fun createLinkTo(entryName: String, owner: SettingsPage): SettingsEntryBuilder { 135 return create(entryName, owner).setLink(toPage = owner) 136 } 137 createnull138 fun create( 139 owner: SettingsPage, 140 entryName: String, 141 label: String = entryName, 142 ): SettingsEntryBuilder = SettingsEntryBuilder(entryName, owner).setLabel(label) 143 144 fun createInject( 145 owner: SettingsPage, 146 label: String = "${INJECT_ENTRY_LABEL}_${owner.displayName}", 147 ): SettingsEntryBuilder = createLinkTo(INJECT_ENTRY_LABEL, owner).setLabel(label) 148 149 fun createRoot( 150 owner: SettingsPage, 151 label: String = "${ROOT_ENTRY_LABEL}_${owner.displayName}", 152 ): SettingsEntryBuilder = createLinkTo(ROOT_ENTRY_LABEL, owner).setLabel(label) 153 } 154 } 155