1 /* 2 * Copyright (C) 2022 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.tests.testutils 18 19 import android.app.Activity 20 import android.content.Context 21 import android.os.Bundle 22 import androidx.compose.material3.Text 23 import androidx.compose.runtime.Composable 24 import androidx.navigation.NavType 25 import androidx.navigation.navArgument 26 import com.android.settingslib.spa.framework.BrowseActivity 27 import com.android.settingslib.spa.framework.common.EntrySearchData 28 import com.android.settingslib.spa.framework.common.EntryStatusData 29 import com.android.settingslib.spa.framework.common.LogCategory 30 import com.android.settingslib.spa.framework.common.LogEvent 31 import com.android.settingslib.spa.framework.common.SettingsEntry 32 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder 33 import com.android.settingslib.spa.framework.common.SettingsPage 34 import com.android.settingslib.spa.framework.common.SettingsPageProvider 35 import com.android.settingslib.spa.framework.common.SettingsPageProviderRepository 36 import com.android.settingslib.spa.framework.common.SpaEnvironment 37 import com.android.settingslib.spa.framework.common.SpaLogger 38 import com.android.settingslib.spa.framework.common.createSettingsPage 39 import com.android.settingslib.spa.widget.preference.SimplePreferenceMacro 40 41 class SpaLoggerForTest : SpaLogger { 42 data class MsgCountKey(val msg: String, val category: LogCategory) 43 data class EventCountKey(val id: String, val event: LogEvent, val category: LogCategory) 44 45 private val messageCount: MutableMap<MsgCountKey, Int> = mutableMapOf() 46 private val eventCount: MutableMap<EventCountKey, Int> = mutableMapOf() 47 messagenull48 override fun message(tag: String, msg: String, category: LogCategory) { 49 val key = MsgCountKey("[$tag]$msg", category) 50 messageCount[key] = (messageCount[key] ?: 0) + 1 51 } 52 eventnull53 override fun event(id: String, event: LogEvent, category: LogCategory, extraData: Bundle) { 54 val key = EventCountKey(id, event, category) 55 eventCount[key] = (eventCount[key] ?: 0) + 1 56 } 57 getMessageCountnull58 fun getMessageCount(tag: String, msg: String, category: LogCategory): Int { 59 val key = MsgCountKey("[$tag]$msg", category) 60 return messageCount[key] ?: 0 61 } 62 getEventCountnull63 fun getEventCount(id: String, event: LogEvent, category: LogCategory): Int { 64 val key = EventCountKey(id, event, category) 65 return eventCount[key] ?: 0 66 } 67 resetnull68 fun reset() { 69 messageCount.clear() 70 eventCount.clear() 71 } 72 } 73 74 class BlankActivity : BrowseActivity() 75 76 object SppHome : SettingsPageProvider { 77 override val name = "SppHome" 78 getTitlenull79 override fun getTitle(arguments: Bundle?): String { 80 return "TitleHome" 81 } 82 buildEntrynull83 override fun buildEntry(arguments: Bundle?): List<SettingsEntry> { 84 val owner = this.createSettingsPage() 85 return listOf( 86 SppLayer1.buildInject().setLink(fromPage = owner).build(), 87 SppDialog.buildInject().setLink(fromPage = owner).build(), 88 ) 89 } 90 } 91 92 object SppDisabled : SettingsPageProvider { 93 override val name = "SppDisabled" 94 isEnablednull95 override fun isEnabled(arguments: Bundle?): Boolean = false 96 97 override fun getTitle(arguments: Bundle?): String { 98 return "TitleDisabled" 99 } 100 buildEntrynull101 override fun buildEntry(arguments: Bundle?): List<SettingsEntry> { 102 val owner = this.createSettingsPage() 103 return listOf( 104 SppLayer1.buildInject().setLink(fromPage = owner).build(), 105 ) 106 } 107 } 108 109 object SppLayer1 : SettingsPageProvider { 110 override val name = "SppLayer1" 111 getTitlenull112 override fun getTitle(arguments: Bundle?): String { 113 return "TitleLayer1" 114 } 115 buildInjectnull116 fun buildInject(): SettingsEntryBuilder { 117 return SettingsEntryBuilder.createInject(this.createSettingsPage()) 118 .setMacro { 119 SimplePreferenceMacro( 120 title = "SppHome to Layer1", 121 clickRoute = name 122 ) 123 } 124 } 125 buildEntrynull126 override fun buildEntry(arguments: Bundle?): List<SettingsEntry> { 127 val owner = this.createSettingsPage() 128 return listOf( 129 SettingsEntryBuilder.create(owner, "Layer1Entry1").build(), 130 SppLayer2.buildInject().setLink(fromPage = owner).build(), 131 SettingsEntryBuilder.create(owner, "Layer1Entry2").build(), 132 ) 133 } 134 } 135 136 object SppLayer2 : SettingsPageProvider { 137 override val name = "SppLayer2" 138 buildInjectnull139 fun buildInject(): SettingsEntryBuilder { 140 return SettingsEntryBuilder.createInject(this.createSettingsPage()) 141 } 142 buildEntrynull143 override fun buildEntry(arguments: Bundle?): List<SettingsEntry> { 144 val owner = this.createSettingsPage() 145 return listOf( 146 SettingsEntryBuilder.create(owner, "Layer2Entry1").build(), 147 SettingsEntryBuilder.create(owner, "Layer2Entry2").build(), 148 ) 149 } 150 } 151 152 object SppDialog : SettingsPageProvider { 153 override val name = "SppDialog" 154 override val navType = SettingsPageProvider.NavType.Dialog 155 156 const val CONTENT = "SppDialog Content" 157 158 @Composable Pagenull159 override fun Page(arguments: Bundle?) { 160 Text(CONTENT) 161 } 162 buildInjectnull163 fun buildInject() = SettingsEntryBuilder.createInject(this.createSettingsPage()) 164 .setMacro { SimplePreferenceMacro(title = name, clickRoute = name) } 165 } 166 167 object SppForSearch : SettingsPageProvider { 168 override val name = "SppForSearch" 169 buildEntrynull170 override fun buildEntry(arguments: Bundle?): List<SettingsEntry> { 171 val owner = this.createSettingsPage() 172 return listOf( 173 SettingsEntryBuilder.create(owner, "SearchStaticWithNoStatus") 174 .setSearchDataFn { EntrySearchData(title = "SearchStaticWithNoStatus") } 175 .build(), 176 SettingsEntryBuilder.create(owner, "SearchStaticWithMutableStatus") 177 .setHasMutableStatus(true) 178 .setSearchDataFn { EntrySearchData(title = "SearchStaticWithMutableStatus") } 179 .setStatusDataFn { EntryStatusData(isSwitchOff = true) } 180 .build(), 181 SettingsEntryBuilder.create(owner, "SearchDynamicWithMutableStatus") 182 .setIsSearchDataDynamic(true) 183 .setHasMutableStatus(true) 184 .setSearchDataFn { EntrySearchData(title = "SearchDynamicWithMutableStatus") } 185 .setStatusDataFn { EntryStatusData(isDisabled = true) } 186 .build(), 187 SettingsEntryBuilder.create(owner, "SearchDynamicWithImmutableStatus") 188 .setIsSearchDataDynamic(true) 189 .setSearchDataFn { 190 EntrySearchData( 191 title = "SearchDynamicWithImmutableStatus", 192 keyword = listOf("kw1", "kw2") 193 ) 194 } 195 .setStatusDataFn { EntryStatusData(isDisabled = true) } 196 .build(), 197 ) 198 } 199 } 200 201 class SpaEnvironmentForTest( 202 context: Context, 203 rootPages: List<SettingsPage> = emptyList(), 204 override val browseActivityClass: Class<out Activity>? = BlankActivity::class.java, 205 override val logger: SpaLogger = object : SpaLogger {} 206 ) : SpaEnvironment(context) { 207 <lambda>null208 override val pageProviderRepository = lazy { 209 SettingsPageProviderRepository( 210 listOf( 211 SppHome, SppLayer1, SppLayer2, 212 SppForSearch, SppDisabled, 213 object : SettingsPageProvider { 214 override val name = "SppWithParam" 215 override val parameter = listOf( 216 navArgument("string_param") { type = NavType.StringType }, 217 navArgument("int_param") { type = NavType.IntType }, 218 ) 219 }, 220 object : SettingsPageProvider { 221 override val name = "SppWithRtParam" 222 override val parameter = listOf( 223 navArgument("string_param") { type = NavType.StringType }, 224 navArgument("int_param") { type = NavType.IntType }, 225 navArgument("rt_param") { type = NavType.StringType }, 226 ) 227 }, 228 SppDialog, 229 ), 230 rootPages 231 ) 232 } 233 createPagenull234 fun createPage(sppName: String, arguments: Bundle? = null): SettingsPage { 235 return pageProviderRepository.value 236 .getProviderOrNull(sppName)!!.createSettingsPage(arguments) 237 } 238 } 239