diff --git a/packages/SettingsLib/Spa/gallery/AndroidManifest.xml b/packages/SettingsLib/Spa/gallery/AndroidManifest.xml index e583138fd88ab..0a4972fac1bb6 100644 --- a/packages/SettingsLib/Spa/gallery/AndroidManifest.xml +++ b/packages/SettingsLib/Spa/gallery/AndroidManifest.xml @@ -18,12 +18,13 @@ package="com.android.settingslib.spa.gallery"> diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryApplication.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryApplication.kt new file mode 100644 index 0000000000000..8c9d42c053d28 --- /dev/null +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryApplication.kt @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2022 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.gallery + +import android.app.Application +import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory + +class GalleryApplication : Application() { + override fun onCreate() { + super.onCreate() + SpaEnvironmentFactory.instance = GallerySpaEnvironment + } +} \ No newline at end of file diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryDebugActivity.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryDebugActivity.kt index 332d5a836c9f5..23072a231417c 100644 --- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryDebugActivity.kt +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryDebugActivity.kt @@ -18,4 +18,4 @@ package com.android.settingslib.spa.gallery import com.android.settingslib.spa.framework.DebugActivity -class GalleryDebugActivity : DebugActivity(GallerySpaEnvironment) +class GalleryDebugActivity : DebugActivity() diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryEntryProvider.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryEntryProvider.kt index 5e048612292dc..817c209fbcdc3 100644 --- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryEntryProvider.kt +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryEntryProvider.kt @@ -18,4 +18,4 @@ package com.android.settingslib.spa.gallery import com.android.settingslib.spa.framework.EntryProvider -class GalleryEntryProvider : EntryProvider(GallerySpaEnvironment) +class GalleryEntryProvider : EntryProvider() diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/MainActivity.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryMainActivity.kt similarity index 92% rename from packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/MainActivity.kt rename to packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryMainActivity.kt index 5e859ce778cf4..08a9bf587f800 100644 --- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/MainActivity.kt +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryMainActivity.kt @@ -18,4 +18,4 @@ package com.android.settingslib.spa.gallery import com.android.settingslib.spa.framework.BrowseActivity -class MainActivity : BrowseActivity(GallerySpaEnvironment) +class GalleryMainActivity : BrowseActivity() diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt index 33c4d7712753f..aa457fe2c8054 100644 --- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt @@ -87,7 +87,7 @@ object GallerySpaEnvironment : SpaEnvironment() { ) } - override val browseActivityClass = MainActivity::class.java + override val browseActivityClass = GalleryMainActivity::class.java override val entryProviderAuthorities = "com.android.spa.gallery.provider" } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt index 8ca1c37a168c1..d87c31b7f95c5 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt @@ -30,7 +30,7 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import com.android.settingslib.spa.R -import com.android.settingslib.spa.framework.common.SpaEnvironment +import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory import com.android.settingslib.spa.framework.compose.LocalNavController import com.android.settingslib.spa.framework.compose.NavControllerWrapperImpl import com.android.settingslib.spa.framework.compose.localNavController @@ -50,8 +50,8 @@ private const val NULL_PAGE_NAME = "NULL" * $ adb shell am start -n -e spa:SpaActivity:destination HOME * $ adb shell am start -n -e spa:SpaActivity:destination ARGUMENT/bar/5 */ -open class BrowseActivity(spaEnvironment: SpaEnvironment) : ComponentActivity() { - private val sppRepository by spaEnvironment.pageProviderRepository +open class BrowseActivity : ComponentActivity() { + private val spaEnvironment get() = SpaEnvironmentFactory.instance override fun onCreate(savedInstanceState: Bundle?) { setTheme(R.style.Theme_SpaLib_DayNight) @@ -67,6 +67,7 @@ open class BrowseActivity(spaEnvironment: SpaEnvironment) : ComponentActivity() @Composable private fun MainContent() { + val sppRepository by spaEnvironment.pageProviderRepository val navController = rememberNavController() CompositionLocalProvider(navController.localNavController()) { NavHost(navController, NULL_PAGE_NAME) { @@ -84,6 +85,7 @@ open class BrowseActivity(spaEnvironment: SpaEnvironment) : ComponentActivity() @Composable private fun InitialDestinationNavigator() { + val sppRepository by spaEnvironment.pageProviderRepository val destinationNavigated = rememberSaveable { mutableStateOf(false) } if (destinationNavigated.value) return destinationNavigated.value = true diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/DebugActivity.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/DebugActivity.kt index ab7c0fe166095..b28da06caf143 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/DebugActivity.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/DebugActivity.kt @@ -37,7 +37,7 @@ import com.android.settingslib.spa.framework.BrowseActivity.Companion.KEY_DESTIN import com.android.settingslib.spa.framework.BrowseActivity.Companion.KEY_HIGHLIGHT_ENTRY import com.android.settingslib.spa.framework.common.SettingsEntry import com.android.settingslib.spa.framework.common.SettingsPage -import com.android.settingslib.spa.framework.common.SpaEnvironment +import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory import com.android.settingslib.spa.framework.compose.localNavController import com.android.settingslib.spa.framework.compose.navigator import com.android.settingslib.spa.framework.compose.toState @@ -63,8 +63,8 @@ private const val PARAM_NAME_ENTRY_ID = "eid" * For gallery, Activity = com.android.settingslib.spa.gallery/.GalleryDebugActivity * For SettingsGoogle, Activity = com.android.settings/.spa.SpaDebugActivity */ -open class DebugActivity(private val spaEnvironment: SpaEnvironment) : ComponentActivity() { - private val entryRepository by spaEnvironment.entryRepository +open class DebugActivity : ComponentActivity() { + private val spaEnvironment get() = SpaEnvironmentFactory.instance override fun onCreate(savedInstanceState: Bundle?) { setTheme(R.style.Theme_SpaLib_DayNight) @@ -128,6 +128,7 @@ open class DebugActivity(private val spaEnvironment: SpaEnvironment) : Component @Composable fun RootPage() { + val entryRepository by spaEnvironment.entryRepository val allPageWithEntry = remember { entryRepository.getAllPageWithEntry() } val allEntry = remember { entryRepository.getAllEntries() } HomeScaffold(title = "Settings Debug") { @@ -141,6 +142,7 @@ open class DebugActivity(private val spaEnvironment: SpaEnvironment) : Component }) Preference(object : PreferenceModel { override val title = "Query EntryProvider" + override val enabled = isEntryProviderAvailable().toState() override val onClick = { displayDebugMessage() } }) } @@ -148,6 +150,7 @@ open class DebugActivity(private val spaEnvironment: SpaEnvironment) : Component @Composable fun AllPages() { + val entryRepository by spaEnvironment.entryRepository val allPageWithEntry = remember { entryRepository.getAllPageWithEntry() } RegularScaffold(title = "All Pages (${allPageWithEntry.size})") { for (pageWithEntry in allPageWithEntry) { @@ -164,6 +167,7 @@ open class DebugActivity(private val spaEnvironment: SpaEnvironment) : Component @Composable fun AllEntries() { + val entryRepository by spaEnvironment.entryRepository val allEntry = remember { entryRepository.getAllEntries() } RegularScaffold(title = "All Entries (${allEntry.size})") { EntryList(allEntry) @@ -172,6 +176,7 @@ open class DebugActivity(private val spaEnvironment: SpaEnvironment) : Component @Composable fun OnePage(arguments: Bundle?) { + val entryRepository by spaEnvironment.entryRepository val id = arguments!!.getString(PARAM_NAME_PAGE_ID, "") val pageWithEntry = entryRepository.getPageWithEntry(id)!! RegularScaffold(title = "Page - ${pageWithEntry.page.displayName}") { @@ -180,7 +185,7 @@ open class DebugActivity(private val spaEnvironment: SpaEnvironment) : Component Text(text = "Entry size: ${pageWithEntry.entries.size}") Preference(model = object : PreferenceModel { override val title = "open page" - override val enabled = (!pageWithEntry.page.hasRuntimeParam()).toState() + override val enabled = isPageClickable(pageWithEntry.page).toState() override val onClick = openPage(pageWithEntry.page) }) EntryList(pageWithEntry.entries) @@ -189,13 +194,14 @@ open class DebugActivity(private val spaEnvironment: SpaEnvironment) : Component @Composable fun OneEntry(arguments: Bundle?) { + val entryRepository by spaEnvironment.entryRepository val id = arguments!!.getString(PARAM_NAME_ENTRY_ID, "") val entry = entryRepository.getEntry(id)!! val entryContent = remember { entry.formatContent() } RegularScaffold(title = "Entry - ${entry.displayTitle()}") { Preference(model = object : PreferenceModel { override val title = "open entry" - override val enabled = (!entry.containerPage().hasRuntimeParam()).toState() + override val enabled = isEntryClickable(entry).toState() override val onClick = openEntry(entry) }) Text(text = entryContent) @@ -216,7 +222,7 @@ open class DebugActivity(private val spaEnvironment: SpaEnvironment) : Component @Composable private fun openPage(page: SettingsPage): (() -> Unit)? { - if (page.hasRuntimeParam()) return null + if (!isPageClickable(page)) return null val context = LocalContext.current val route = page.buildRoute() val intent = Intent(context, spaEnvironment.browseActivityClass).apply { @@ -230,7 +236,7 @@ open class DebugActivity(private val spaEnvironment: SpaEnvironment) : Component @Composable private fun openEntry(entry: SettingsEntry): (() -> Unit)? { - if (entry.containerPage().hasRuntimeParam()) return null + if (!isEntryClickable(entry)) return null val context = LocalContext.current val route = entry.containerPage().buildRoute() val intent = Intent(context, spaEnvironment.browseActivityClass).apply { @@ -242,4 +248,17 @@ open class DebugActivity(private val spaEnvironment: SpaEnvironment) : Component context.startActivity(intent) } } + + private fun isEntryProviderAvailable(): Boolean { + return spaEnvironment.entryProviderAuthorities != null + } + + private fun isPageClickable(page: SettingsPage): Boolean { + return spaEnvironment.browseActivityClass != null && !page.hasRuntimeParam() + } + + private fun isEntryClickable(entry: SettingsEntry): Boolean { + return spaEnvironment.browseActivityClass != null && + !entry.containerPage().hasRuntimeParam() + } } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/EntryProvider.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/EntryProvider.kt index 50157fc61fb12..532f63b67c5db 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/EntryProvider.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/EntryProvider.kt @@ -30,7 +30,7 @@ import android.net.Uri import android.util.Log import com.android.settingslib.spa.framework.common.SettingsEntry import com.android.settingslib.spa.framework.common.SettingsPage -import com.android.settingslib.spa.framework.common.SpaEnvironment +import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory private const val TAG = "EntryProvider" @@ -49,9 +49,8 @@ private const val TAG = "EntryProvider" * $ adb shell content query --uri content:///search_static * $ adb shell content query --uri content:///search_dynamic */ -open class EntryProvider(spaEnvironment: SpaEnvironment) : ContentProvider() { - private val entryRepository by spaEnvironment.entryRepository - private val browseActivityClass = spaEnvironment.browseActivityClass +open class EntryProvider : ContentProvider() { + private val spaEnvironment get() = SpaEnvironmentFactory.instance /** * Enum to define all column names in provider. @@ -221,6 +220,7 @@ open class EntryProvider(spaEnvironment: SpaEnvironment) : ContentProvider() { } private fun queryPageDebug(): Cursor { + val entryRepository by spaEnvironment.entryRepository val cursor = MatrixCursor(QueryEnum.PAGE_DEBUG_QUERY.getColumns()) for (pageWithEntry in entryRepository.getAllPageWithEntry()) { val command = createBrowsePageAdbCommand(pageWithEntry.page) @@ -232,6 +232,7 @@ open class EntryProvider(spaEnvironment: SpaEnvironment) : ContentProvider() { } private fun queryEntryDebug(): Cursor { + val entryRepository by spaEnvironment.entryRepository val cursor = MatrixCursor(QueryEnum.ENTRY_DEBUG_QUERY.getColumns()) for (entry in entryRepository.getAllEntries()) { val command = createBrowsePageAdbCommand(entry.containerPage(), entry.id) @@ -243,6 +244,7 @@ open class EntryProvider(spaEnvironment: SpaEnvironment) : ContentProvider() { } private fun queryPageInfo(): Cursor { + val entryRepository by spaEnvironment.entryRepository val cursor = MatrixCursor(QueryEnum.PAGE_INFO_QUERY.getColumns()) for (pageWithEntry in entryRepository.getAllPageWithEntry()) { val page = pageWithEntry.page @@ -261,6 +263,7 @@ open class EntryProvider(spaEnvironment: SpaEnvironment) : ContentProvider() { } private fun queryEntryInfo(): Cursor { + val entryRepository by spaEnvironment.entryRepository val cursor = MatrixCursor(QueryEnum.ENTRY_INFO_QUERY.getColumns()) for (entry in entryRepository.getAllEntries()) { cursor.newRow() @@ -276,6 +279,7 @@ open class EntryProvider(spaEnvironment: SpaEnvironment) : ContentProvider() { } private fun querySearchSitemap(): Cursor { + val entryRepository by spaEnvironment.entryRepository val cursor = MatrixCursor(QueryEnum.SEARCH_SITEMAP_QUERY.getColumns()) for (entry in entryRepository.getAllEntries()) { if (!entry.isAllowSearch) continue @@ -287,6 +291,7 @@ open class EntryProvider(spaEnvironment: SpaEnvironment) : ContentProvider() { } private fun querySearchStaticData(): Cursor { + val entryRepository by spaEnvironment.entryRepository val cursor = MatrixCursor(QueryEnum.SEARCH_STATIC_DATA_QUERY.getColumns()) for (entry in entryRepository.getAllEntries()) { if (!entry.isAllowSearch || entry.isSearchDataDynamic) continue @@ -296,6 +301,7 @@ open class EntryProvider(spaEnvironment: SpaEnvironment) : ContentProvider() { } private fun querySearchDynamicData(): Cursor { + val entryRepository by spaEnvironment.entryRepository val cursor = MatrixCursor(QueryEnum.SEARCH_DYNAMIC_DATA_QUERY.getColumns()) for (entry in entryRepository.getAllEntries()) { if (!entry.isAllowSearch || !entry.isSearchDataDynamic) continue @@ -317,26 +323,31 @@ open class EntryProvider(spaEnvironment: SpaEnvironment) : ContentProvider() { } private fun createBrowsePageIntent(page: SettingsPage, entryId: String? = null): Intent { - if (context == null || page.hasRuntimeParam()) - return Intent() - - return Intent().setComponent(ComponentName(context!!, browseActivityClass)).apply { - putExtra(BrowseActivity.KEY_DESTINATION, page.buildRoute()) - if (entryId != null) { - putExtra(BrowseActivity.KEY_HIGHLIGHT_ENTRY, entryId) + if (!isPageBrowsable(page)) return Intent() + return Intent().setComponent(ComponentName(context!!, spaEnvironment.browseActivityClass!!)) + .apply { + putExtra(BrowseActivity.KEY_DESTINATION, page.buildRoute()) + if (entryId != null) { + putExtra(BrowseActivity.KEY_HIGHLIGHT_ENTRY, entryId) + } } - } } private fun createBrowsePageAdbCommand(page: SettingsPage, entryId: String? = null): String? { - if (context == null || page.hasRuntimeParam()) return null + if (!isPageBrowsable(page)) return null val packageName = context!!.packageName - val activityName = browseActivityClass.name.replace(packageName, "") + val activityName = spaEnvironment.browseActivityClass!!.name.replace(packageName, "") val destinationParam = " -e ${BrowseActivity.KEY_DESTINATION} ${page.buildRoute()}" val highlightParam = if (entryId != null) " -e ${BrowseActivity.KEY_HIGHLIGHT_ENTRY} $entryId" else "" return "adb shell am start -n $packageName/$activityName$destinationParam$highlightParam" } + + private fun isPageBrowsable(page: SettingsPage): Boolean { + return context != null && + spaEnvironment.browseActivityClass != null && + !page.hasRuntimeParam() + } } fun EntryProvider.QueryEnum.getColumns(): Array { diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaEnvironment.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaEnvironment.kt index 111555b468c1b..3885025652f52 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaEnvironment.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaEnvironment.kt @@ -18,12 +18,28 @@ package com.android.settingslib.spa.framework.common import android.app.Activity +object SpaEnvironmentFactory { + private var spaEnvironment: SpaEnvironment? = null + + var instance: SpaEnvironment + get() { + if (spaEnvironment == null) + throw UnsupportedOperationException("Spa environment is not set") + return spaEnvironment!! + } + set(env: SpaEnvironment) { + if (spaEnvironment != null) + throw UnsupportedOperationException("Spa environment is already set") + spaEnvironment = env + } +} + abstract class SpaEnvironment { abstract val pageProviderRepository: Lazy val entryRepository = lazy { SettingsEntryRepository(pageProviderRepository.value) } - abstract val browseActivityClass: Class + open val browseActivityClass: Class? = null open val entryProviderAuthorities: String? = null