Merge "Remove IdAndComplicationData from the public API" into androidx-main
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/ErrorMessagesTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/ErrorMessagesTest.kt
index 2fbbab8..ba63e9f 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/ErrorMessagesTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/ErrorMessagesTest.kt
@@ -30,7 +30,6 @@
 import androidx.compose.ui.semantics.SemanticsActions
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.util.expectErrorMessage
-import androidx.compose.ui.test.util.expectErrorMessageMatches
 import androidx.compose.ui.test.util.expectErrorMessageStartsWith
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
@@ -62,10 +61,10 @@
         }
 
         expectErrorMessage(
-            "" +
-                "Failed: assertExists.\n" +
-                "Reason: Expected exactly '1' node but could not find any node that satisfies: " +
-                "(TestTag = 'MyButton3')"
+            """
+                Failed: assertExists.
+                Reason: Expected exactly '1' node but could not find any node that satisfies: (TestTag = 'MyButton3')
+            """.trimIndent()
         ) {
             rule.onNodeWithTag("MyButton3")
                 .assertExists()
@@ -79,10 +78,11 @@
         }
 
         expectErrorMessage(
-            "" +
-                "Failed to perform a gesture.\n" +
-                "Reason: Expected exactly '1' node but could not find any node that satisfies: " +
-                "(TestTag = 'MyButton3')"
+            """
+                Failed to perform a gesture.
+                Reason: Expected exactly '1' node but could not find any node that satisfies: (TestTag = 'MyButton3')
+            """.trimIndent()
+
         ) {
             rule.onNodeWithTag("MyButton3")
                 .performClick()
@@ -96,10 +96,10 @@
         }
 
         expectErrorMessage(
-            "" +
-                "Failed to perform a gesture.\n" +
-                "Reason: Expected exactly '1' node but could not find any node that satisfies: " +
-                "((TestTag = 'MyButton3') && (OnClick is defined))"
+            """
+                Failed to perform a gesture.
+                Reason: Expected exactly '1' node but could not find any node that satisfies: ((TestTag = 'MyButton3') && (OnClick is defined))
+            """.trimIndent()
         ) {
             rule.onNode(hasTestTag("MyButton3") and hasClickAction())
                 .performClick()
@@ -113,12 +113,12 @@
         }
 
         expectErrorMessageStartsWith(
-            "" +
-                "Failed to perform a gesture.\n" +
-                "Reason: Expected exactly '1' node but found '2' nodes that satisfy: " +
-                "(Text = 'Toggle' (ignoreCase: false))\n" +
-                "Nodes found:\n" +
-                "1) Node #X at (l=X, t=X, r=X, b=X)px, Tag: 'MyButton'"
+            """
+                Failed to perform a gesture.
+                Reason: Expected exactly '1' node but found '2' nodes that satisfy: (Text = 'Toggle' (ignoreCase: false))
+                Nodes found:
+                1) Node #X at (l=X, t=X, r=X, b=X)px, Tag: 'MyButton'
+            """.trimIndent()
         ) {
             rule.onNodeWithText("Toggle")
                 .performClick()
@@ -132,10 +132,10 @@
         }
 
         expectErrorMessageStartsWith(
-            "" +
-                "Failed to perform OnClick action.\n" +
-                "Reason: Expected exactly '1' node but could not find any node that satisfies: " +
-                "(TestTag = 'MyButton3')"
+            """
+                Failed to perform OnClick action.
+                Reason: Expected exactly '1' node but could not find any node that satisfies: (TestTag = 'MyButton3')
+            """.trimIndent()
         ) {
             rule.onNodeWithTag("MyButton3")
                 .performSemanticsAction(SemanticsActions.OnClick)
@@ -149,12 +149,12 @@
         }
 
         expectErrorMessageStartsWith(
-            "" +
-                "Failed: assertDoesNotExist.\n" +
-                "Reason: Did not expect any node but found '1' node that satisfies: " +
-                "(TestTag = 'MyButton')\n" +
-                "Node found:\n" +
-                "Node #X at (l=X, t=X, r=X, b=X)px, Tag: 'MyButton'"
+            """
+                Failed: assertDoesNotExist.
+                Reason: Did not expect any node but found '1' node that satisfies: (TestTag = 'MyButton')
+                Node found:
+                Node #X at (l=X, t=X, r=X, b=X)px, Tag: 'MyButton'
+            """.trimIndent()
         ) {
             rule.onNodeWithTag("MyButton")
                 .assertDoesNotExist()
@@ -168,12 +168,12 @@
         }
 
         expectErrorMessageStartsWith(
-            "" +
-                "Failed to assert count of nodes.\n" +
-                "Reason: Expected '3' nodes but found '2' nodes that satisfy: " +
-                "(Text = 'Toggle' (ignoreCase: false))\n" +
-                "Nodes found:\n" +
-                "1) Node #X at (l=X, t=X, r=X, b=X)px"
+            """
+                Failed to assert count of nodes.
+                Reason: Expected '3' nodes but found '2' nodes that satisfy: (Text = 'Toggle' (ignoreCase: false))
+                Nodes found:
+                1) Node #X at (l=X, t=X, r=X, b=X)px
+            """.trimIndent()
         ) {
             rule.onAllNodesWithText("Toggle")
                 .assertCountEquals(3)
@@ -187,10 +187,10 @@
         }
 
         expectErrorMessage(
-            "" +
-                "Failed to assert count of nodes.\n" +
-                "Reason: Expected '3' nodes but could not find any node that satisfies: " +
-                "(Text = 'Toggle2' (ignoreCase: false))"
+            """
+                Failed to assert count of nodes.
+                Reason: Expected '3' nodes but could not find any node that satisfies: (Text = 'Toggle2' (ignoreCase: false))
+            """.trimIndent()
         ) {
             rule.onAllNodesWithText("Toggle2")
                 .assertCountEquals(3)
@@ -209,15 +209,16 @@
         rule.onNodeWithTag("MyButton")
             .performClick()
 
-        expectErrorMessageMatches(
-            "" +
-                "Failed to perform a gesture.\n" +
-                "The node is no longer in the tree, last known semantics:\n" +
-                "Node #X at \\(l=X, t=X, r=X, b=X\\)px\n" +
-                "Text = 'Hello'\n" +
-                "GetTextLayoutResult = 'AccessibilityAction\\(label=null, action=.*\\)'\n" +
-                "Has 1 sibling\n" +
-                "Original selector: Text = 'Hello' \\(ignoreCase: false\\)"
+        expectErrorMessage(
+            """
+                Failed to perform a gesture.
+                The node is no longer in the tree, last known semantics:
+                Node #X at (l=X, t=X, r=X, b=X)px
+                Text = 'Hello'
+                Actions = [GetTextLayoutResult]
+                Has 1 sibling
+                Original selector: Text = 'Hello' (ignoreCase: false)
+            """.trimIndent()
         ) {
             node.performClick()
         }
@@ -236,15 +237,16 @@
         rule.onNodeWithTag("MyButton")
             .performClick()
 
-        expectErrorMessageMatches(
-            "" +
-                "Failed: assertExists.\n" +
-                "The node is no longer in the tree, last known semantics:\n" +
-                "Node #X at \\(l=X, t=X, r=X, b=X\\)px\n" +
-                "Text = 'Hello'\n" +
-                "GetTextLayoutResult = 'AccessibilityAction\\(label=null, action=.*\\)'\n" +
-                "Has 1 sibling\n" +
-                "Original selector: Text = 'Hello' \\(ignoreCase: false\\)"
+        expectErrorMessage(
+            """
+                Failed: assertExists.
+                The node is no longer in the tree, last known semantics:
+                Node #X at (l=X, t=X, r=X, b=X)px
+                Text = 'Hello'
+                Actions = [GetTextLayoutResult]
+                Has 1 sibling
+                Original selector: Text = 'Hello' (ignoreCase: false)
+            """.trimIndent()
         ) {
             node.assertExists()
         }
@@ -263,15 +265,16 @@
         rule.onNodeWithTag("MyButton")
             .performClick()
 
-        expectErrorMessageMatches(
-            "" +
-                "Failed to assert the following: \\(OnClick is defined\\)\n" +
-                "The node is no longer in the tree, last known semantics:\n" +
-                "Node #X at \\(l=X, t=X, r=X, b=X\\)px\n" +
-                "Text = 'Hello'\n" +
-                "GetTextLayoutResult = 'AccessibilityAction\\(label=null, action=.*\\)'\n" +
-                "Has 1 sibling\n" +
-                "Original selector: Text = 'Hello' \\(ignoreCase: false\\)"
+        expectErrorMessage(
+            """
+                Failed to assert the following: (OnClick is defined)
+                The node is no longer in the tree, last known semantics:
+                Node #X at (l=X, t=X, r=X, b=X)px
+                Text = 'Hello'
+                Actions = [GetTextLayoutResult]
+                Has 1 sibling
+                Original selector: Text = 'Hello' (ignoreCase: false)
+            """.trimIndent()
         ) {
             node.assertHasClickAction()
         }
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/PrintToStringTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/PrintToStringTest.kt
index bdf172f..3d7c59b 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/PrintToStringTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/PrintToStringTest.kt
@@ -67,12 +67,14 @@
         val result = rule.onNodeWithText("Hello")
             .printToString(maxDepth = 0)
 
-        assertThat(obfuscateNodesInfo(result)).matches(
-            "" +
-                "Node #X at \\(l=X, t=X, r=X, b=X\\)px\n" +
-                "Text = 'Hello'\n" +
-                "GetTextLayoutResult = 'AccessibilityAction\\(label=null, action=.*\\)'\n" +
-                "Has 1 sibling"
+        assertThat(obfuscateNodesInfo(result)).isEqualTo(
+            """
+                Printing with useUnmergedTree = 'false'
+                Node #X at (l=X, t=X, r=X, b=X)px
+                Text = 'Hello'
+                Actions = [GetTextLayoutResult]
+                Has 1 sibling
+            """.trimIndent()
         )
     }
 
@@ -86,16 +88,18 @@
             .onChildren()
             .printToString()
 
-        assertThat(obfuscateNodesInfo(result)).matches(
-            "" +
-                "1\\) Node #X at \\(l=X, t=X, r=X, b=X\\)px\n" +
-                "Text = 'Hello'\n" +
-                "GetTextLayoutResult = 'AccessibilityAction\\(label=null, action=.*\\)'\n" +
-                "Has 1 sibling\n" +
-                "2\\) Node #X at \\(l=X, t=X, r=X, b=X\\)px\n" +
-                "Text = 'World'\n" +
-                "GetTextLayoutResult = 'AccessibilityAction\\(label=null, action=.*\\)'\n" +
-                "Has 1 sibling"
+        assertThat(obfuscateNodesInfo(result)).isEqualTo(
+            """
+                Printing with useUnmergedTree = 'false'
+                1) Node #X at (l=X, t=X, r=X, b=X)px
+                Text = 'Hello'
+                Actions = [GetTextLayoutResult]
+                Has 1 sibling
+                2) Node #X at (l=X, t=X, r=X, b=X)px
+                Text = 'World'
+                Actions = [GetTextLayoutResult]
+                Has 1 sibling
+            """.trimIndent()
         )
     }
 
@@ -115,23 +119,23 @@
         val result = rule.onRoot()
             .printToString()
 
-        assertThat(obfuscateNodesInfo(result)).matches(
-            "" +
-                "Node #X at \\(l=X, t=X, r=X, b=X\\)px\n" +
-                " ..*Node #X at \\(l=X, t=X, r=X, b=X\\)px, Tag: 'column'\n" +
-                "   Disabled = 'kotlin.Unit'\n" +
-                "    .-Node #X at \\(l=X, t=X, r=X, b=X\\)px, Tag: 'box'\n" +
-                "    . Disabled = 'kotlin.Unit'\n" +
-                "    .  .-Node #X at \\(l=X, t=X, r=X, b=X\\)px\n" +
-                "    .    Role = 'Button'\n" +
-                "    .    OnClick = 'AccessibilityAction\\(label=null, action=.*\\)'\n" +
-                "    .    Text = 'Button'\n" +
-                "    .    GetTextLayoutResult = 'AccessibilityAction\\(label=null, " +
-                "action=.*\\)'\n" +
-                "    .    MergeDescendants = 'true'\n" +
-                "    .-Node #X at \\(l=X, t=X, r=X, b=X\\)px\n" +
-                "      Text = 'Hello'\n" +
-                "      GetTextLayoutResult = 'AccessibilityAction\\(label=null, action=.*\\).*'"
+        assertThat(obfuscateNodesInfo(result)).isEqualTo(
+            """
+                Printing with useUnmergedTree = 'false'
+                Node #X at (l=X, t=X, r=X, b=X)px
+                 |-Node #X at (l=X, t=X, r=X, b=X)px, Tag: 'column'
+                   [Disabled]
+                    |-Node #X at (l=X, t=X, r=X, b=X)px, Tag: 'box'
+                    | [Disabled]
+                    |  |-Node #X at (l=X, t=X, r=X, b=X)px
+                    |    Role = 'Button'
+                    |    Text = 'Button'
+                    |    Actions = [OnClick, GetTextLayoutResult]
+                    |    MergeDescendants = 'true'
+                    |-Node #X at (l=X, t=X, r=X, b=X)px
+                      Text = 'Hello'
+                      Actions = [GetTextLayoutResult]
+            """.trimIndent()
         )
     }
 
@@ -155,13 +159,15 @@
             .printToString(maxDepth = 1)
 
         assertThat(obfuscateNodesInfo(result)).isEqualTo(
-            "" +
-                "1) Node #X at (l=X, t=X, r=X, b=X)px, Tag: 'tag1'\n" +
-                " |-Node #X at (l=X, t=X, r=X, b=X)px, Tag: 'tag11'\n" +
-                "   Has 1 child\n" +
-                "2) Node #X at (l=X, t=X, r=X, b=X)px, Tag: 'tag2'\n" +
-                " |-Node #X at (l=X, t=X, r=X, b=X)px, Tag: 'tag22'\n" +
-                "   Has 1 child"
+            """
+                Printing with useUnmergedTree = 'false'
+                1) Node #X at (l=X, t=X, r=X, b=X)px, Tag: 'tag1'
+                 |-Node #X at (l=X, t=X, r=X, b=X)px, Tag: 'tag11'
+                   Has 1 child
+                2) Node #X at (l=X, t=X, r=X, b=X)px, Tag: 'tag2'
+                 |-Node #X at (l=X, t=X, r=X, b=X)px, Tag: 'tag22'
+                   Has 1 child
+            """.trimIndent()
         )
     }
 
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/util/Output.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/util/Output.kt
index 83d6af9..a67ef92 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/util/Output.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/util/Output.kt
@@ -40,18 +40,6 @@
     throw AssertionError("No AssertionError thrown!")
 }
 
-internal fun expectErrorMessageMatches(expectedErrorMessage: String, block: () -> Unit) {
-    try {
-        block()
-    } catch (e: AssertionError) {
-        val received = obfuscateNodesInfo(e.localizedMessage!!)
-        Truth.assertThat(received).matches(expectedErrorMessage.trim())
-        return
-    }
-
-    throw AssertionError("No AssertionError thrown!")
-}
-
 internal fun expectErrorMessageStartsWith(expectedErrorMessage: String, block: () -> Unit) {
     try {
         block()
diff --git a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Output.kt b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Output.kt
index f2780d1..5ac3060 100644
--- a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Output.kt
+++ b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/Output.kt
@@ -17,6 +17,7 @@
 package androidx.compose.ui.test
 
 import androidx.compose.ui.geometry.Rect
+import androidx.compose.ui.semantics.AccessibilityAction
 import androidx.compose.ui.semantics.SemanticsConfiguration
 import androidx.compose.ui.semantics.SemanticsNode
 import androidx.compose.ui.semantics.SemanticsProperties
@@ -42,7 +43,8 @@
     maxDepth: Int = Int.MAX_VALUE
 ): String {
     val result = fetchSemanticsNode()
-    return result.printToString(maxDepth)
+    return "Printing with useUnmergedTree = '$useUnmergedTree'\n" +
+        result.printToString(maxDepth)
 }
 
 /**
@@ -84,11 +86,12 @@
     maxDepth: Int = 0
 ): String {
     val nodes = fetchSemanticsNodes()
-    return if (nodes.isEmpty()) {
-        "There were 0 nodes found!"
-    } else {
-        nodes.printToString(maxDepth)
-    }
+    return "Printing with useUnmergedTree = '$useUnmergedTree'\n" +
+        if (nodes.isEmpty()) {
+            "There were 0 nodes found!"
+        } else {
+            nodes.printToString(maxDepth)
+        }
 }
 
 /**
@@ -218,11 +221,25 @@
 }
 
 private fun StringBuilder.appendConfigInfo(config: SemanticsConfiguration, indent: String = "") {
+    val actions = mutableListOf<String>()
+    val units = mutableListOf<String>()
     for ((key, value) in config) {
         if (key == SemanticsProperties.TestTag) {
             continue
         }
 
+        if (value is AccessibilityAction<*>) {
+            // Avoids printing stuff like "action = 'AccessibilityAction\(label=null, action=.*\)'"
+            actions.add(key.name)
+            continue
+        }
+
+        if (value is Unit) {
+            // Avoids printing stuff like "Disabled = 'kotlin.Unit'"
+            units.add(key.name)
+            continue
+        }
+
         appendLine()
         append(indent)
         append(key.name)
@@ -244,6 +261,22 @@
         append("'")
     }
 
+    if (units.isNotEmpty()) {
+        appendLine()
+        append(indent)
+        append("[")
+        append(units.joinToString(separator = ", "))
+        append("]")
+    }
+
+    if (actions.isNotEmpty()) {
+        appendLine()
+        append(indent)
+        append("Actions = [")
+        append(actions.joinToString(separator = ", "))
+        append("]")
+    }
+
     if (config.isMergingSemanticsOfDescendants) {
         appendLine()
         append(indent)
diff --git a/wear/wear-watchface/guava/build.gradle b/wear/wear-watchface/guava/build.gradle
index 642c937..a70be6e 100644
--- a/wear/wear-watchface/guava/build.gradle
+++ b/wear/wear-watchface/guava/build.gradle
@@ -31,6 +31,12 @@
     api(project(":wear:wear-watchface"))
     api(GUAVA_LISTENABLE_FUTURE)
 
+    androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
+    androidTestImplementation(ANDROIDX_TEST_CORE)
+    androidTestImplementation(ANDROIDX_TEST_RUNNER)
+    androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+    androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
+    androidTestImplementation(TRUTH)
     testImplementation(ANDROIDX_TEST_CORE)
     testImplementation(ANDROIDX_TEST_RUNNER)
     testImplementation(ANDROIDX_TEST_RULES)
diff --git a/wear/wear-watchface/guava/src/androidTest/java/AsyncListenableWatchFaceServiceTest.kt b/wear/wear-watchface/guava/src/androidTest/java/AsyncListenableWatchFaceServiceTest.kt
new file mode 100644
index 0000000..1736917
--- /dev/null
+++ b/wear/wear-watchface/guava/src/androidTest/java/AsyncListenableWatchFaceServiceTest.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2021 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.
+ */
+
+import android.graphics.Canvas
+import android.graphics.Rect
+import android.icu.util.Calendar
+import android.os.Handler
+import android.os.Looper
+import android.view.SurfaceHolder
+import androidx.wear.watchface.CanvasType
+import androidx.wear.watchface.ListenableWatchFaceService
+import androidx.wear.watchface.MutableWatchState
+import androidx.wear.watchface.Renderer
+import androidx.wear.watchface.WatchFace
+import androidx.wear.watchface.WatchFaceType
+import androidx.wear.watchface.WatchState
+import androidx.wear.watchface.style.UserStyleRepository
+import androidx.wear.watchface.style.UserStyleSchema
+import com.google.common.truth.Truth.assertThat
+import com.google.common.util.concurrent.ListenableFuture
+import com.google.common.util.concurrent.SettableFuture
+import kotlinx.coroutines.runBlocking
+import org.junit.Test
+import org.mockito.Mockito
+
+private const val REFERENCE_PREVIEW_TIME = 123456L
+
+private class FakeRenderer(
+    surfaceHolder: SurfaceHolder,
+    watchState: WatchState,
+    userStyleRepository: UserStyleRepository
+) : Renderer.CanvasRenderer(
+    surfaceHolder,
+    userStyleRepository,
+    watchState,
+    CanvasType.SOFTWARE,
+    16
+) {
+    override fun render(canvas: Canvas, bounds: Rect, calendar: Calendar) {
+    }
+}
+
+private class TestAsyncListenableWatchFaceService(private val handler: Handler) :
+    ListenableWatchFaceService() {
+    override fun createWatchFaceFuture(
+        surfaceHolder: SurfaceHolder,
+        watchState: WatchState
+    ): ListenableFuture<WatchFace> {
+        val future = SettableFuture.create<WatchFace>()
+        val userStyleRepository = UserStyleRepository(
+            UserStyleSchema(emptyList())
+        )
+        // Post a task to resolve the future.
+        handler.post {
+            future.set(
+                WatchFace(
+                    WatchFaceType.DIGITAL,
+                    userStyleRepository,
+                    FakeRenderer(surfaceHolder, watchState, userStyleRepository)
+                ).apply { setOverridePreviewReferenceTimeMillis(REFERENCE_PREVIEW_TIME) }
+            )
+        }
+        return future
+    }
+
+    suspend fun createWatchFaceForTest(
+        surfaceHolder: SurfaceHolder,
+        watchState: WatchState
+    ): WatchFace = createWatchFace(surfaceHolder, watchState)
+}
+
+/**
+ * Illustrates that createWatchFaceFuture can be resolved in a different task posted to the main
+ * looper.
+ */
+public class AsyncListenableWatchFaceServiceTest {
+
+    @Test
+    public fun asyncTest() {
+        val handler = Handler(Looper.getMainLooper())
+        val service = TestAsyncListenableWatchFaceService(handler)
+        val mockSurfaceHolder = Mockito.mock(SurfaceHolder::class.java)
+        Mockito.`when`(mockSurfaceHolder.surfaceFrame).thenReturn(Rect(0, 0, 100, 100))
+
+        runBlocking {
+            val watchFace = service.createWatchFaceForTest(
+                mockSurfaceHolder,
+                MutableWatchState().asWatchState()
+            )
+
+            // Simple check that [watchFace] looks sensible.
+            assertThat(watchFace.overridePreviewReferenceTimeMillis).isEqualTo(
+                REFERENCE_PREVIEW_TIME
+            )
+        }
+    }
+}
\ No newline at end of file
diff --git a/wear/wear-watchface/guava/src/test/java/androidx/wear/watchface/ListenableWatchFaceServiceTest.kt b/wear/wear-watchface/guava/src/test/java/androidx/wear/watchface/ListenableWatchFaceServiceTest.kt
index 095e53f..272465f 100644
--- a/wear/wear-watchface/guava/src/test/java/androidx/wear/watchface/ListenableWatchFaceServiceTest.kt
+++ b/wear/wear-watchface/guava/src/test/java/androidx/wear/watchface/ListenableWatchFaceServiceTest.kt
@@ -98,4 +98,4 @@
         )
             .doNotInstrumentPackage("androidx.wear.watchface")
             .build()
-}
\ No newline at end of file
+}