Merge changes from topic "compose-build-flag" into tm-qpr-dev am: 93df848cf1

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20759151

Change-Id: I6106efa4b1842fb57deb0522ca47b2c1314a6d08
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 42a5dde..788fe30 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -31,6 +31,52 @@
     ],
 }
 
+// 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 @@
 
 android_library {
     name: "SystemUI-core",
+    defaults: [
+        "SystemUI_compose_defaults",
+    ],
     srcs: [
         "src/**/*.kt",
         "src/**/*.java",
@@ -227,6 +276,9 @@
 
 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 0000000..6e728ce
--- /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 0000000..16294d9
--- /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 325ede6..4533330 100644
--- a/packages/SystemUI/compose/features/Android.bp
+++ b/packages/SystemUI/compose/features/Android.bp
@@ -35,6 +35,7 @@
 
         "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 0000000..e5ec727
--- /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 7cc95a1..fba5f63 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 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 @@
         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<PeopleViewModel.Result, Unit> 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) {