Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b42fe7c3 authored by Steve Elliott's avatar Steve Elliott
Browse files

Move Kosmos to its own build module

Bug: 302691505
Flag: NA
Test: atest
Change-Id: I0f2fbf525fb37133f801d07e62eb3f4cf89e26c6
parent b591ee96
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -197,13 +197,30 @@ filegroup {
    path: "tests/src",
}

filegroup {
    name: "kosmos-src",
    srcs: ["tests/utils/kosmos/src/**/*.kt"],
    path: "tests/utils/kosmos",
}

java_library {
    name: "kosmos",
    host_supported: true,
    srcs: [":kosmos-src"],
    static_libs: [
        "kotlin-reflect",
        "kotlin-stdlib",
    ],
}

filegroup {
    name: "SystemUI-tests-utils",
    srcs: [
        "tests/utils/src/**/*.java",
        "tests/utils/src/**/*.kt",
        ":kosmos-src",
    ],
    path: "tests/utils/src",
    path: "tests/utils",
}

filegroup {
@@ -336,6 +353,7 @@ android_library {
        "kotlin-test",
        "SystemUICustomizationTestUtils",
        "androidx.compose.runtime_runtime",
        "kosmos",
    ],
    libs: [
        "android.test.runner",
@@ -419,6 +437,7 @@ android_robolectric_test {
        "inline-mockito-robolectric-prebuilt",
        "platform-parametric-runner-lib",
        "SystemUICustomizationTestUtils",
        "kosmos",
    ],
    libs: [
        "android.test.runner",
@@ -452,6 +471,7 @@ android_ravenwood_test {
        "androidx.test.uiautomator_uiautomator",
        "androidx.core_core-animation-testing",
        "androidx.test.ext.junit",
        "kosmos",
    ],
    libs: [
        "android.test.runner",
+97 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.kosmos

import kotlin.reflect.KProperty
@@ -5,6 +21,7 @@ import kotlin.reflect.KProperty
// (Historical note: The name Kosmos is meant to invoke "Kotlin", the "Object Mother" pattern
//   (https://martinfowler.com/bliki/ObjectMother.html), and of course the Greek word "kosmos" for
//   the "order of the world" (https://en.wiktionary.org/wiki/%CE%BA%CF%8C%CF%83%CE%BC%CE%BF%CF%82)

/**
 * Each Kosmos is its own self-contained set of fixtures, which may reference each other. Fixtures
 * can be defined through extension properties in any file:
@@ -29,9 +46,15 @@ import kotlin.reflect.KProperty
 * )
 * ```
 */
class Kosmos {
    private val map: MutableMap<String, Any?> = mutableMapOf()
    private val gotten: MutableSet<String> = mutableSetOf()
interface Kosmos {
    /**
     * Lookup a fixture in the Kosmos by [name], using [creator] to instantiate and store one if
     * there is none present.
     */
    fun <T> get(name: String, creator: (Kosmos.() -> T)?): T

    /** Sets the [value] of a fixture with the given [name]. */
    fun set(name: String, value: Any?)

    /**
     * A value in the kosmos that has a single value once it's read. It can be overridden before
@@ -42,28 +65,33 @@ class Kosmos {
     * If no [creator] parameter is provided, the fixture must be set before use.
     */
    class Fixture<T>(private val creator: (Kosmos.() -> T)? = null) {
        operator fun getValue(thisRef: Kosmos, property: KProperty<*>): T {
            thisRef.gotten.add(property.name)
            @Suppress("UNCHECKED_CAST")
            if (!thisRef.map.contains(property.name)) {
                if (creator == null) {
                    throw IllegalStateException(
                        "Fixture ${property.name} has no default, and is read before set."
                    )
                } else {
                    val nonNullCreator = creator
                    // The Kotlin compiler seems to need this odd workaround
                    thisRef.map[property.name] = thisRef.nonNullCreator()
        operator fun getValue(thisRef: Kosmos, property: KProperty<*>): T =
            thisRef.get(property.name, creator)

        operator fun setValue(thisRef: Kosmos, property: KProperty<*>, value: T) {
            thisRef.set(property.name, value)
        }
    }
            return thisRef.map[property.name] as T
}

        operator fun setValue(thisRef: Kosmos, property: KProperty<*>, value: T) {
            check(!thisRef.gotten.contains(property.name)) {
                "Tried to set fixture '${property.name}' after it's already been read."
/** Constructs a fresh Kosmos. */
fun Kosmos(): Kosmos = KosmosRegistry()

private class KosmosRegistry : Kosmos {
    val map: MutableMap<String, Any?> = mutableMapOf()
    val gotten: MutableSet<String> = mutableSetOf()

    override fun <T> get(name: String, creator: (Kosmos.() -> T)?): T {
        gotten.add(name)
        if (name !in map) {
            checkNotNull(creator) { "Fixture $name has no default, and is read before set." }
            map[name] = creator()
        }
            thisRef.map[property.name] = value
        @Suppress("UNCHECKED_CAST") return map[name] as T
    }

    override fun set(name: String, value: Any?) {
        check(name !in gotten) { "Tried to set fixture '$name' after it's already been read." }
        map[name] = value
    }
}