From 616b9606a33b6d52825718d66eaa99b1daa4b17a Mon Sep 17 00:00:00 2001 From: Zekan Qian Date: Thu, 2 Feb 2023 15:47:57 +0800 Subject: [PATCH] Code refactoring. Split Entry & EntryBuilder into separate files Move getTitle function to SettingsPage Bug: 244122804 Test: unit-test & local build gallery Change-Id: I3cf034fc70a7d74ac9394e1dc1804051db9a6b09 --- .../spa/framework/common/SettingsEntry.kt | 144 --------------- .../framework/common/SettingsEntryBuilder.kt | 165 ++++++++++++++++++ .../common/SettingsEntryRepository.kt | 8 +- .../spa/framework/common/SettingsPage.kt | 4 + .../common/SettingsEntryRepositoryTest.kt | 1 + 5 files changed, 172 insertions(+), 150 deletions(-) create mode 100644 packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryBuilder.kt diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntry.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntry.kt index 4b73e948e1e64..b92729dab7c05 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntry.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntry.kt @@ -24,10 +24,6 @@ import androidx.compose.runtime.ProvidedValue import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.remember import com.android.settingslib.spa.framework.compose.LocalNavController -import com.android.settingslib.spa.framework.util.genEntryId - -private const val INJECT_ENTRY_NAME = "INJECT" -private const val ROOT_ENTRY_NAME = "ROOT" interface EntryData { val pageId: String? @@ -164,143 +160,3 @@ data class SettingsEntry( } } } - -/** - * The helper to build a Settings Entry instance. - */ -class SettingsEntryBuilder(private val name: String, private val owner: SettingsPage) { - private var displayName = name - private var fromPage: SettingsPage? = null - private var toPage: SettingsPage? = null - - // Attributes - private var isAllowSearch: Boolean = false - private var isSearchDataDynamic: Boolean = false - private var hasMutableStatus: Boolean = false - private var hasSliceSupport: Boolean = false - - // Functions - private var uiLayoutFn: UiLayerRenderer = { } - private var statusDataFn: StatusDataGetter = { null } - private var searchDataFn: SearchDataGetter = { null } - private var sliceDataFn: SliceDataGetter = { _: Uri, _: Bundle? -> null } - - fun build(): SettingsEntry { - val page = fromPage ?: owner - val isEnabled = page.isEnabled() - return SettingsEntry( - id = genEntryId(name, owner, fromPage, toPage), - name = name, - owner = owner, - displayName = displayName, - - // linking data - fromPage = fromPage, - toPage = toPage, - - // attributes - // TODO: set isEnabled & (isAllowSearch, hasSliceSupport) separately - isAllowSearch = isEnabled && isAllowSearch, - isSearchDataDynamic = isSearchDataDynamic, - hasMutableStatus = hasMutableStatus, - hasSliceSupport = isEnabled && hasSliceSupport, - - // functions - statusDataImpl = statusDataFn, - searchDataImpl = searchDataFn, - sliceDataImpl = sliceDataFn, - uiLayoutImpl = uiLayoutFn, - ) - } - - fun setDisplayName(displayName: String): SettingsEntryBuilder { - this.displayName = displayName - return this - } - - fun setLink( - fromPage: SettingsPage? = null, - toPage: SettingsPage? = null - ): SettingsEntryBuilder { - if (fromPage != null) this.fromPage = fromPage - if (toPage != null) this.toPage = toPage - return this - } - - fun setIsSearchDataDynamic(isDynamic: Boolean): SettingsEntryBuilder { - this.isSearchDataDynamic = isDynamic - return this - } - - fun setHasMutableStatus(hasMutableStatus: Boolean): SettingsEntryBuilder { - this.hasMutableStatus = hasMutableStatus - return this - } - - fun setMacro(fn: (arguments: Bundle?) -> EntryMacro): SettingsEntryBuilder { - setStatusDataFn { fn(it).getStatusData() } - setSearchDataFn { fn(it).getSearchData() } - setUiLayoutFn { - val macro = remember { fn(it) } - macro.UiLayout() - } - return this - } - - fun setStatusDataFn(fn: StatusDataGetter): SettingsEntryBuilder { - this.statusDataFn = fn - return this - } - - fun setSearchDataFn(fn: SearchDataGetter): SettingsEntryBuilder { - this.searchDataFn = fn - this.isAllowSearch = true - return this - } - - fun clearSearchDataFn(): SettingsEntryBuilder { - this.searchDataFn = { null } - this.isAllowSearch = false - return this - } - - fun setSliceDataFn(fn: SliceDataGetter): SettingsEntryBuilder { - this.sliceDataFn = fn - this.hasSliceSupport = true - return this - } - - fun setUiLayoutFn(fn: UiLayerRenderer): SettingsEntryBuilder { - this.uiLayoutFn = fn - return this - } - - companion object { - fun create(entryName: String, owner: SettingsPage): SettingsEntryBuilder { - return SettingsEntryBuilder(entryName, owner) - } - - fun createLinkFrom(entryName: String, owner: SettingsPage): SettingsEntryBuilder { - return create(entryName, owner).setLink(fromPage = owner) - } - - fun createLinkTo(entryName: String, owner: SettingsPage): SettingsEntryBuilder { - return create(entryName, owner).setLink(toPage = owner) - } - - fun create(owner: SettingsPage, entryName: String, displayName: String? = null): - SettingsEntryBuilder { - return SettingsEntryBuilder(entryName, owner).setDisplayName(displayName ?: entryName) - } - - fun createInject(owner: SettingsPage, displayName: String? = null): SettingsEntryBuilder { - val name = displayName ?: "${INJECT_ENTRY_NAME}_${owner.displayName}" - return createLinkTo(INJECT_ENTRY_NAME, owner).setDisplayName(name) - } - - fun createRoot(owner: SettingsPage, displayName: String? = null): SettingsEntryBuilder { - val name = displayName ?: "${ROOT_ENTRY_NAME}_${owner.displayName}" - return createLinkTo(ROOT_ENTRY_NAME, owner).setDisplayName(name) - } - } -} diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryBuilder.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryBuilder.kt new file mode 100644 index 0000000000000..67f9ea52a40d2 --- /dev/null +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryBuilder.kt @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spa.framework.common + +import android.net.Uri +import android.os.Bundle +import androidx.compose.runtime.remember +import com.android.settingslib.spa.framework.util.genEntryId + +private const val INJECT_ENTRY_NAME = "INJECT" +private const val ROOT_ENTRY_NAME = "ROOT" + +/** + * The helper to build a Settings Entry instance. + */ +class SettingsEntryBuilder(private val name: String, private val owner: SettingsPage) { + private var displayName = name + private var fromPage: SettingsPage? = null + private var toPage: SettingsPage? = null + + // Attributes + private var isAllowSearch: Boolean = false + private var isSearchDataDynamic: Boolean = false + private var hasMutableStatus: Boolean = false + private var hasSliceSupport: Boolean = false + + // Functions + private var uiLayoutFn: UiLayerRenderer = { } + private var statusDataFn: StatusDataGetter = { null } + private var searchDataFn: SearchDataGetter = { null } + private var sliceDataFn: SliceDataGetter = { _: Uri, _: Bundle? -> null } + + fun build(): SettingsEntry { + val page = fromPage ?: owner + val isEnabled = page.isEnabled() + return SettingsEntry( + id = genEntryId(name, owner, fromPage, toPage), + name = name, + owner = owner, + displayName = displayName, + + // linking data + fromPage = fromPage, + toPage = toPage, + + // attributes + // TODO: set isEnabled & (isAllowSearch, hasSliceSupport) separately + isAllowSearch = isEnabled && isAllowSearch, + isSearchDataDynamic = isSearchDataDynamic, + hasMutableStatus = hasMutableStatus, + hasSliceSupport = isEnabled && hasSliceSupport, + + // functions + statusDataImpl = statusDataFn, + searchDataImpl = searchDataFn, + sliceDataImpl = sliceDataFn, + uiLayoutImpl = uiLayoutFn, + ) + } + + fun setDisplayName(displayName: String): SettingsEntryBuilder { + this.displayName = displayName + return this + } + + fun setLink( + fromPage: SettingsPage? = null, + toPage: SettingsPage? = null + ): SettingsEntryBuilder { + if (fromPage != null) this.fromPage = fromPage + if (toPage != null) this.toPage = toPage + return this + } + + fun setIsSearchDataDynamic(isDynamic: Boolean): SettingsEntryBuilder { + this.isSearchDataDynamic = isDynamic + return this + } + + fun setHasMutableStatus(hasMutableStatus: Boolean): SettingsEntryBuilder { + this.hasMutableStatus = hasMutableStatus + return this + } + + fun setMacro(fn: (arguments: Bundle?) -> EntryMacro): SettingsEntryBuilder { + setStatusDataFn { fn(it).getStatusData() } + setSearchDataFn { fn(it).getSearchData() } + setUiLayoutFn { + val macro = remember { fn(it) } + macro.UiLayout() + } + return this + } + + fun setStatusDataFn(fn: StatusDataGetter): SettingsEntryBuilder { + this.statusDataFn = fn + return this + } + + fun setSearchDataFn(fn: SearchDataGetter): SettingsEntryBuilder { + this.searchDataFn = fn + this.isAllowSearch = true + return this + } + + fun clearSearchDataFn(): SettingsEntryBuilder { + this.searchDataFn = { null } + this.isAllowSearch = false + return this + } + + fun setSliceDataFn(fn: SliceDataGetter): SettingsEntryBuilder { + this.sliceDataFn = fn + this.hasSliceSupport = true + return this + } + + fun setUiLayoutFn(fn: UiLayerRenderer): SettingsEntryBuilder { + this.uiLayoutFn = fn + return this + } + + companion object { + fun create(entryName: String, owner: SettingsPage): SettingsEntryBuilder { + return SettingsEntryBuilder(entryName, owner) + } + + fun createLinkFrom(entryName: String, owner: SettingsPage): SettingsEntryBuilder { + return create(entryName, owner).setLink(fromPage = owner) + } + + fun createLinkTo(entryName: String, owner: SettingsPage): SettingsEntryBuilder { + return create(entryName, owner).setLink(toPage = owner) + } + + fun create(owner: SettingsPage, entryName: String, displayName: String? = null): + SettingsEntryBuilder { + return SettingsEntryBuilder(entryName, owner).setDisplayName(displayName ?: entryName) + } + + fun createInject(owner: SettingsPage, displayName: String? = null): SettingsEntryBuilder { + val name = displayName ?: "${INJECT_ENTRY_NAME}_${owner.displayName}" + return createLinkTo(INJECT_ENTRY_NAME, owner).setDisplayName(name) + } + + fun createRoot(owner: SettingsPage, displayName: String? = null): SettingsEntryBuilder { + val name = displayName ?: "${ROOT_ENTRY_NAME}_${owner.displayName}" + return createLinkTo(ROOT_ENTRY_NAME, owner).setDisplayName(name) + } + } +} diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryRepository.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryRepository.kt index 14dc7857dbc71..7aeefd23d1160 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryRepository.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryRepository.kt @@ -30,14 +30,10 @@ data class SettingsPageWithEntry( val injectEntry: SettingsEntry, ) -private fun SettingsPage.getTitle(sppRepository: SettingsPageProviderRepository): String { - return sppRepository.getProviderOrNull(sppName)!!.getTitle(arguments) -} - /** * The repository to maintain all Settings entries */ -class SettingsEntryRepository(private val sppRepository: SettingsPageProviderRepository) { +class SettingsEntryRepository(sppRepository: SettingsPageProviderRepository) { // Map of entry unique Id to entry private val entryMap: Map @@ -123,7 +119,7 @@ class SettingsEntryRepository(private val sppRepository: SettingsPageProviderRep if (it.toPage == null) defaultTitle else { - it.toPage.getTitle(sppRepository) + it.toPage.getTitle() } } } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt index c810648524b94..724588f794b46 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt @@ -81,6 +81,10 @@ data class SettingsPage( return getPageProvider(sppName)?.isEnabled(arguments) ?: false } + fun getTitle(): String { + return getPageProvider(sppName)?.getTitle(arguments) ?: "" + } + @Composable fun UiLayout() { getPageProvider(sppName)?.Page(arguments) diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryRepositoryTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryRepositoryTest.kt index 730aa8f95e632..379b9a7db09b2 100644 --- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryRepositoryTest.kt +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryRepositoryTest.kt @@ -113,6 +113,7 @@ class SettingsEntryRepositoryTest { @Test fun testGetEntryPath() { + SpaEnvironmentFactory.reset(spaEnvironment) assertThat( entryRepository.getEntryPathWithDisplayName( genEntryId("Layer2Entry1", SppLayer2.createSettingsPage())