1 /* <lambda>null2 * 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.net.Uri 20 import android.os.Bundle 21 import androidx.compose.runtime.remember 22 import com.android.settingslib.spa.framework.util.genEntryId 23 24 private const val INJECT_ENTRY_LABEL = "INJECT" 25 private const val ROOT_ENTRY_LABEL = "ROOT" 26 27 /** 28 * The helper to build a Settings Entry instance. 29 */ 30 class SettingsEntryBuilder(private val name: String, private val owner: SettingsPage) { 31 private var label = name 32 private var fromPage: SettingsPage? = null 33 private var toPage: SettingsPage? = null 34 35 // Attributes 36 private var isAllowSearch: Boolean = false 37 private var isSearchDataDynamic: Boolean = false 38 private var hasMutableStatus: Boolean = false 39 private var hasSliceSupport: Boolean = false 40 41 // Functions 42 private var uiLayoutFn: UiLayerRenderer = { } 43 private var statusDataFn: StatusDataGetter = { null } 44 private var searchDataFn: SearchDataGetter = { null } 45 private var sliceDataFn: SliceDataGetter = { _: Uri, _: Bundle? -> null } 46 47 fun build(): SettingsEntry { 48 val page = fromPage ?: owner 49 val isEnabled = page.isEnabled() 50 return SettingsEntry( 51 id = genEntryId(name, owner, fromPage, toPage), 52 name = name, 53 owner = owner, 54 label = label, 55 56 // linking data 57 fromPage = fromPage, 58 toPage = toPage, 59 60 // attributes 61 // TODO: set isEnabled & (isAllowSearch, hasSliceSupport) separately 62 isAllowSearch = isEnabled && isAllowSearch, 63 isSearchDataDynamic = isSearchDataDynamic, 64 hasMutableStatus = hasMutableStatus, 65 hasSliceSupport = isEnabled && hasSliceSupport, 66 67 // functions 68 statusDataImpl = statusDataFn, 69 searchDataImpl = searchDataFn, 70 sliceDataImpl = sliceDataFn, 71 uiLayoutImpl = uiLayoutFn, 72 ) 73 } 74 75 fun setLabel(label: String): SettingsEntryBuilder { 76 this.label = label 77 return this 78 } 79 80 fun setLink( 81 fromPage: SettingsPage? = null, 82 toPage: SettingsPage? = null 83 ): SettingsEntryBuilder { 84 if (fromPage != null) this.fromPage = fromPage 85 if (toPage != null) this.toPage = toPage 86 return this 87 } 88 89 fun setIsSearchDataDynamic(isDynamic: Boolean): SettingsEntryBuilder { 90 this.isSearchDataDynamic = isDynamic 91 return this 92 } 93 94 fun setHasMutableStatus(hasMutableStatus: Boolean): SettingsEntryBuilder { 95 this.hasMutableStatus = hasMutableStatus 96 return this 97 } 98 99 fun setMacro(fn: (arguments: Bundle?) -> EntryMacro): SettingsEntryBuilder { 100 setStatusDataFn { fn(it).getStatusData() } 101 setSearchDataFn { fn(it).getSearchData() } 102 setUiLayoutFn { 103 val macro = remember { fn(it) } 104 macro.UiLayout() 105 } 106 return this 107 } 108 109 fun setStatusDataFn(fn: StatusDataGetter): SettingsEntryBuilder { 110 this.statusDataFn = fn 111 return this 112 } 113 114 fun setSearchDataFn(fn: SearchDataGetter): SettingsEntryBuilder { 115 this.searchDataFn = fn 116 this.isAllowSearch = true 117 return this 118 } 119 120 fun clearSearchDataFn(): SettingsEntryBuilder { 121 this.searchDataFn = { null } 122 this.isAllowSearch = false 123 return this 124 } 125 126 fun setSliceDataFn(fn: SliceDataGetter): SettingsEntryBuilder { 127 this.sliceDataFn = fn 128 this.hasSliceSupport = true 129 return this 130 } 131 132 fun setUiLayoutFn(fn: UiLayerRenderer): SettingsEntryBuilder { 133 this.uiLayoutFn = fn 134 return this 135 } 136 137 companion object { 138 fun create(entryName: String, owner: SettingsPage): SettingsEntryBuilder { 139 return SettingsEntryBuilder(entryName, owner) 140 } 141 142 fun createLinkFrom(entryName: String, owner: SettingsPage): SettingsEntryBuilder { 143 return create(entryName, owner).setLink(fromPage = owner) 144 } 145 146 fun createLinkTo(entryName: String, owner: SettingsPage): SettingsEntryBuilder { 147 return create(entryName, owner).setLink(toPage = owner) 148 } 149 150 fun create( 151 owner: SettingsPage, 152 entryName: String, 153 label: String = entryName, 154 ): SettingsEntryBuilder = SettingsEntryBuilder(entryName, owner).setLabel(label) 155 156 fun createInject( 157 owner: SettingsPage, 158 label: String = "${INJECT_ENTRY_LABEL}_${owner.displayName}", 159 ): SettingsEntryBuilder = createLinkTo(INJECT_ENTRY_LABEL, owner).setLabel(label) 160 161 fun createRoot( 162 owner: SettingsPage, 163 label: String = "${ROOT_ENTRY_LABEL}_${owner.displayName}", 164 ): SettingsEntryBuilder = createLinkTo(ROOT_ENTRY_LABEL, owner).setLabel(label) 165 } 166 } 167