diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index 25fb24a3417fc..6b4d5ae86d1e9 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -31,6 +31,52 @@ license { ], } +// Opt-in configuration for code depending on Jetpack Compose. +soong_config_module_type { + name: "systemui_compose_java_defaults", + module_type: "java_defaults", + config_namespace: "ANDROID", + bool_variables: ["SYSTEMUI_USE_COMPOSE"], + properties: [ + "srcs", + "static_libs", + ], +} + +systemui_compose_java_defaults { + name: "SystemUI_compose_defaults", + soong_config_variables: { + SYSTEMUI_USE_COMPOSE: { + // Because files in compose/features/ depend on SystemUI + // code, we compile those files when compiling SystemUI-core. + // We also compile the ComposeFacade in + // compose/facade/enabled/. + srcs: [ + "compose/features/src/**/*.kt", + "compose/facade/enabled/src/**/*.kt", + ], + + // The dependencies needed by SystemUIComposeFeatures, + // except for SystemUI-core. + // Copied from compose/features/Android.bp. + static_libs: [ + "SystemUIComposeCore", + + "androidx.compose.runtime_runtime", + "androidx.compose.material3_material3", + "androidx.activity_activity-compose", + ], + + // By default, Compose is disabled and we compile the ComposeFacade + // in compose/facade/disabled/. + conditions_default: { + srcs: ["compose/facade/disabled/src/**/*.kt"], + static_libs: [], + }, + }, + }, +} + java_library { name: "SystemUI-proto", @@ -68,6 +114,9 @@ filegroup { android_library { name: "SystemUI-core", + defaults: [ + "SystemUI_compose_defaults", + ], srcs: [ "src/**/*.kt", "src/**/*.java", @@ -227,6 +276,9 @@ android_library { android_library { name: "SystemUI-tests", + defaults: [ + "SystemUI_compose_defaults", + ], manifest: "tests/AndroidManifest-base.xml", additional_manifests: ["tests/AndroidManifest.xml"], srcs: [ diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt new file mode 100644 index 0000000000000..6e728ce7248f1 --- /dev/null +++ b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt @@ -0,0 +1,41 @@ +/* + * 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.systemui.compose + +import androidx.activity.ComponentActivity +import com.android.systemui.people.ui.viewmodel.PeopleViewModel + +/** The Compose facade, when Compose is *not* available. */ +object ComposeFacade : BaseComposeFacade { + override fun isComposeAvailable(): Boolean = false + + override fun setPeopleSpaceActivityContent( + activity: ComponentActivity, + viewModel: PeopleViewModel, + onResult: (PeopleViewModel.Result) -> Unit, + ) { + throwComposeUnavailableError() + } + + private fun throwComposeUnavailableError() { + error( + "Compose is not available. Make sure to check isComposeAvailable() before calling any" + + " other function on ComposeFacade." + ) + } +} diff --git a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt new file mode 100644 index 0000000000000..16294d9c19772 --- /dev/null +++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt @@ -0,0 +1,36 @@ +/* + * 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.systemui.compose + +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import com.android.systemui.compose.theme.SystemUITheme +import com.android.systemui.people.ui.compose.PeopleScreen +import com.android.systemui.people.ui.viewmodel.PeopleViewModel + +/** The Compose facade, when Compose is available. */ +object ComposeFacade : BaseComposeFacade { + override fun isComposeAvailable(): Boolean = true + + override fun setPeopleSpaceActivityContent( + activity: ComponentActivity, + viewModel: PeopleViewModel, + onResult: (PeopleViewModel.Result) -> Unit, + ) { + activity.setContent { SystemUITheme { PeopleScreen(viewModel, onResult) } } + } +} diff --git a/packages/SystemUI/compose/features/Android.bp b/packages/SystemUI/compose/features/Android.bp index 325ede613de8e..4533330531180 100644 --- a/packages/SystemUI/compose/features/Android.bp +++ b/packages/SystemUI/compose/features/Android.bp @@ -35,6 +35,7 @@ android_library { "androidx.compose.runtime_runtime", "androidx.compose.material3_material3", + "androidx.activity_activity-compose", ], kotlincflags: ["-Xjvm-default=all"], diff --git a/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt b/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt new file mode 100644 index 0000000000000..e5ec727f04379 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt @@ -0,0 +1,44 @@ +/* + * 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.systemui.compose + +import androidx.activity.ComponentActivity +import com.android.systemui.people.ui.viewmodel.PeopleViewModel + +/** + * A facade to interact with Compose, when it is available. + * + * You should access this facade by calling the static methods on + * [com.android.systemui.compose.ComposeFacade] directly. + */ +interface BaseComposeFacade { + /** + * Whether Compose is currently available. This function should be checked before calling any + * other functions on this facade. + * + * This value will never change at runtime. + */ + fun isComposeAvailable(): Boolean + + /** Bind the content of [activity] to [viewModel]. */ + fun setPeopleSpaceActivityContent( + activity: ComponentActivity, + viewModel: PeopleViewModel, + onResult: (PeopleViewModel.Result) -> Unit, + ) +} diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java index 7cc95a158a140..fba5f63ea9c78 100644 --- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java +++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java @@ -27,11 +27,15 @@ import android.view.ViewGroup; import androidx.activity.ComponentActivity; import androidx.lifecycle.ViewModelProvider; +import com.android.systemui.compose.ComposeFacade; import com.android.systemui.people.ui.view.PeopleViewBinder; import com.android.systemui.people.ui.viewmodel.PeopleViewModel; import javax.inject.Inject; +import kotlin.Unit; +import kotlin.jvm.functions.Function1; + /** People Tile Widget configuration activity that shows the user their conversation tiles. */ public class PeopleSpaceActivity extends ComponentActivity { @@ -58,13 +62,18 @@ public class PeopleSpaceActivity extends ComponentActivity { int widgetId = getIntent().getIntExtra(EXTRA_APPWIDGET_ID, INVALID_APPWIDGET_ID); viewModel.onWidgetIdChanged(widgetId); - ViewGroup view = PeopleViewBinder.create(this); - PeopleViewBinder.bind(view, viewModel, /* lifecycleOwner= */ this, - (result) -> { - finishActivity(result); - return null; - }); - setContentView(view); + Function1 onResult = (result) -> { + finishActivity(result); + return null; + }; + + if (ComposeFacade.INSTANCE.isComposeAvailable()) { + ComposeFacade.INSTANCE.setPeopleSpaceActivityContent(this, viewModel, onResult); + } else { + ViewGroup view = PeopleViewBinder.create(this); + PeopleViewBinder.bind(view, viewModel, /* lifecycleOwner= */ this, onResult); + setContentView(view); + } } private void finishActivity(PeopleViewModel.Result result) {