Merge "Gallery Template 1: Update Glance Gallery Data API and Condensed View" into androidx-main
diff --git a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/SingleEntityWidget.kt b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/SingleEntityWidget.kt
index ef8e33a..ede3b8a 100644
--- a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/SingleEntityWidget.kt
+++ b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/SingleEntityWidget.kt
@@ -30,13 +30,13 @@
 import androidx.glance.appwidget.action.actionRunCallback
 import androidx.glance.appwidget.state.updateAppWidgetState
 import androidx.glance.appwidget.template.GlanceTemplateAppWidget
-import androidx.glance.currentState
 import androidx.glance.appwidget.template.SingleEntityTemplate
+import androidx.glance.currentState
 import androidx.glance.template.SingleEntityTemplateData
 import androidx.glance.template.TemplateImageWithDescription
 import androidx.glance.template.TemplateText
 import androidx.glance.template.TemplateTextButton
-import androidx.glance.template.TemplateText.Type
+import androidx.glance.template.TextType
 
 private val PressedKey = booleanPreferencesKey("pressedKey")
 
@@ -70,13 +70,13 @@
 }
 
 private fun createData(title: String) = SingleEntityTemplateData(
-    header = TemplateText("Single Entity demo", Type.Title),
+    header = TemplateText("Single Entity demo", TextType.Title),
     headerIcon = TemplateImageWithDescription(
         ImageProvider(R.drawable.compose),
         "Header icon"
     ),
-    text1 = TemplateText(title, Type.Title),
-    text2 = TemplateText("Subtitle test", Type.Title),
+    text1 = TemplateText(title, TextType.Title),
+    text2 = TemplateText("Subtitle test", TextType.Title),
     button = TemplateTextButton(actionRunCallback<ButtonAction>(), "toggle"),
     image = TemplateImageWithDescription(
         ImageProvider(R.drawable.compose),
diff --git a/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/DemoOverrideWidget.kt b/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/DemoOverrideWidget.kt
index 0e3d961..e7d93f4 100644
--- a/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/DemoOverrideWidget.kt
+++ b/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/DemoOverrideWidget.kt
@@ -23,21 +23,22 @@
 import androidx.glance.ImageProvider
 import androidx.glance.appwidget.GlanceAppWidget
 import androidx.glance.appwidget.GlanceAppWidgetReceiver
+import androidx.glance.appwidget.template.GlanceTemplateAppWidget
+import androidx.glance.appwidget.template.SingleEntityTemplate
 import androidx.glance.background
 import androidx.glance.layout.Alignment
 import androidx.glance.layout.Column
 import androidx.glance.layout.fillMaxSize
+import androidx.glance.template.LocalTemplateMode
+import androidx.glance.template.SingleEntityTemplateData
+import androidx.glance.template.TemplateImageWithDescription
+import androidx.glance.template.TemplateMode
+import androidx.glance.template.TemplateText
+import androidx.glance.template.TextType
 import androidx.glance.text.Text
 import androidx.glance.text.TextAlign
 import androidx.glance.text.TextStyle
 import androidx.glance.unit.ColorProvider
-import androidx.glance.appwidget.template.GlanceTemplateAppWidget
-import androidx.glance.appwidget.template.SingleEntityTemplate
-import androidx.glance.template.LocalTemplateMode
-import androidx.glance.template.SingleEntityTemplateData
-import androidx.glance.template.TemplateMode
-import androidx.glance.template.TemplateImageWithDescription
-import androidx.glance.template.TemplateText
 
 /**
  * A widget implementation that uses [SingleEntityTemplate] with a custom layout override for
@@ -52,16 +53,16 @@
         } else {
             SingleEntityTemplate(
                 SingleEntityTemplateData(
-                    header = TemplateText("Single Entity Demo", TemplateText.Type.Title),
+                    header = TemplateText("Single Entity Demo", TextType.Title),
                     headerIcon = TemplateImageWithDescription(
                         ImageProvider(R.drawable.compose),
                         "icon"
                     ),
-                    text1 = TemplateText("title", TemplateText.Type.Title),
-                    text2 = TemplateText("Subtitle", TemplateText.Type.Label),
+                    text1 = TemplateText("title", TextType.Title),
+                    text2 = TemplateText("Subtitle", TextType.Label),
                     text3 = TemplateText(
                         "Body Lorem ipsum dolor sit amet, consectetur adipiscing",
-                        TemplateText.Type.Label
+                        TextType.Label
                     ),
                     image = TemplateImageWithDescription(ImageProvider(R.drawable.compose), "image")
                 )
diff --git a/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/GalleryDemoWidget.kt b/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/GalleryDemoWidget.kt
index 917f568..cb4eac1 100644
--- a/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/GalleryDemoWidget.kt
+++ b/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/GalleryDemoWidget.kt
@@ -17,15 +17,19 @@
 package androidx.glance.appwidget.template.demos
 
 import androidx.compose.runtime.Composable
+import androidx.glance.ImageProvider
 import androidx.glance.appwidget.GlanceAppWidget
 import androidx.glance.appwidget.GlanceAppWidgetReceiver
-import androidx.glance.ImageProvider
 import androidx.glance.appwidget.SizeMode
-import androidx.glance.unit.ColorProvider
 import androidx.glance.appwidget.template.GalleryTemplate
 import androidx.glance.appwidget.template.GlanceTemplateAppWidget
 import androidx.glance.template.GalleryTemplateData
+import androidx.glance.template.HeaderBlock
+import androidx.glance.template.ImageBlock
 import androidx.glance.template.TemplateImageWithDescription
+import androidx.glance.template.TemplateText
+import androidx.glance.template.TextBlock
+import androidx.glance.template.TextType
 
 /**
  * A widget that uses [GalleryTemplate].
@@ -35,17 +39,42 @@
 
     @Composable
     override fun TemplateContent() {
+        val galleryContent = mutableListOf<TemplateImageWithDescription>()
+        for (i in 1..8) {
+            galleryContent.add(
+                TemplateImageWithDescription(
+                    ImageProvider(R.drawable.compose),
+                    "gallery image $i"
+                )
+            )
+        }
         GalleryTemplate(
             GalleryTemplateData(
-                header = "Gallery Template example",
-                title = "Gallery Template title",
-                headline = "Gallery Template headline",
-                image = TemplateImageWithDescription(
-                    ImageProvider(R.drawable.compose),
-                    "test image"
+                header = HeaderBlock(
+                    text = TemplateText("Gallery Template example"),
+                    icon = TemplateImageWithDescription(
+                        ImageProvider(R.drawable.compose),
+                        "test logo"
+                    ),
                 ),
-                logo = TemplateImageWithDescription(ImageProvider(R.drawable.compose), "test logo"),
-                backgroundColor = ColorProvider(R.color.default_widget_background)
+                mainTextBlock = TextBlock(
+                    text1 = TemplateText("Gallery Template title", TextType.Title),
+                    text2 = TemplateText("Gallery Template headline", TextType.Headline),
+                    priority = 0,
+                ),
+                mainImageBlock = ImageBlock(
+                    images = listOf(
+                        TemplateImageWithDescription(
+                            ImageProvider(R.drawable.compose),
+                            "test image"
+                        )
+                    ),
+                    priority = 1,
+                ),
+                galleryImageBlock = ImageBlock(
+                    images = galleryContent,
+                    priority = 2,
+                ),
             )
         )
     }
diff --git a/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/ListDemoWidget.kt b/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/ListDemoWidget.kt
index d55bac6..23bcab3 100644
--- a/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/ListDemoWidget.kt
+++ b/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/ListDemoWidget.kt
@@ -43,6 +43,7 @@
 import androidx.glance.template.TemplateImageButton
 import androidx.glance.template.TemplateImageWithDescription
 import androidx.glance.template.TemplateText
+import androidx.glance.template.TextType
 import androidx.glance.unit.ColorProvider
 
 /**
@@ -144,12 +145,12 @@
             }
             content.add(
                 ListTemplateItem(
-                    title = TemplateText("Title Medium", TemplateText.Type.Title),
+                    title = TemplateText("Title Medium", TextType.Title),
                     body = TemplateText(
                         "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
-                        TemplateText.Type.Body
+                        TextType.Body
                     ),
-                    label = TemplateText(label, TemplateText.Type.Label),
+                    label = TemplateText(label, TextType.Label),
                     image = TemplateImageWithDescription(ImageProvider(R.drawable.compose), "$i"),
                     button = TemplateImageButton(
                         itemSelectAction(
@@ -168,7 +169,7 @@
             ListTemplateData(
                 header = if (showHeader) TemplateText(
                     "List Demo",
-                    TemplateText.Type.Title
+                    TextType.Title
                 ) else null,
                 headerIcon = if (showHeader) TemplateImageWithDescription(
                     ImageProvider(R.drawable.ic_widget),
diff --git a/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/SingleEntityDemoWidget.kt b/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/SingleEntityDemoWidget.kt
index 4dae917..aad35b6 100644
--- a/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/SingleEntityDemoWidget.kt
+++ b/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/SingleEntityDemoWidget.kt
@@ -35,8 +35,8 @@
 import androidx.glance.template.SingleEntityTemplateData
 import androidx.glance.template.TemplateImageWithDescription
 import androidx.glance.template.TemplateText
-import androidx.glance.template.TemplateText.Type
 import androidx.glance.template.TemplateTextButton
+import androidx.glance.template.TextType
 
 /**
  * Demo app widget using [SingleEntityTemplate] to define layout.
@@ -48,18 +48,18 @@
     override fun TemplateContent() {
         SingleEntityTemplate(
             SingleEntityTemplateData(
-                header = TemplateText("Single Entity Demo", Type.Title),
+                header = TemplateText("Single Entity Demo", TextType.Title),
                 headerIcon = TemplateImageWithDescription(
                     ImageProvider(R.drawable.compose),
                     "Header icon"
                 ),
                 text1 = TemplateText(
-                    getTitle(currentState<Preferences>()[ToggleKey] == true), Type.Title
+                    getTitle(currentState<Preferences>()[ToggleKey] == true), TextType.Title
                 ),
-                text2 = TemplateText("Subtitle", Type.Label),
+                text2 = TemplateText("Subtitle", TextType.Label),
                 text3 = TemplateText(
                     "Body Lorem ipsum dolor sit amet, consectetur adipiscing elit",
-                    Type.Body
+                    TextType.Body
                 ),
                 button = TemplateTextButton(
                     actionRunCallback<SEButtonAction>(),
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/FreeformTemplateLayouts.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/FreeformTemplateLayouts.kt
index ac33065..115feec 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/FreeformTemplateLayouts.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/FreeformTemplateLayouts.kt
@@ -30,6 +30,7 @@
 import androidx.glance.template.LocalTemplateMode
 import androidx.glance.template.TemplateMode
 import androidx.glance.template.TemplateText
+import androidx.glance.template.TextType
 import androidx.glance.unit.ColorProvider
 
 /**
@@ -100,10 +101,10 @@
 ): List<TemplateText> {
     val result = mutableListOf<TemplateText>()
     title?.let {
-        result.add(TemplateText(it.text, TemplateText.Type.Title))
+        result.add(TemplateText(it.text, TextType.Title))
     }
     subtitle?.let {
-        result.add(TemplateText(it.text, TemplateText.Type.Label))
+        result.add(TemplateText(it.text, TextType.Label))
     }
 
     return result
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/GalleryTemplateLayouts.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/GalleryTemplateLayouts.kt
index ea5443d..2489d93 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/GalleryTemplateLayouts.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/GalleryTemplateLayouts.kt
@@ -23,12 +23,14 @@
 import androidx.glance.background
 import androidx.glance.layout.Alignment
 import androidx.glance.layout.Column
+import androidx.glance.layout.ContentScale
 import androidx.glance.layout.Row
 import androidx.glance.layout.Spacer
 import androidx.glance.layout.fillMaxSize
 import androidx.glance.layout.padding
 import androidx.glance.layout.width
 import androidx.glance.template.GalleryTemplateData
+import androidx.glance.template.LocalTemplateColors
 import androidx.glance.template.LocalTemplateMode
 import androidx.glance.template.TemplateMode
 import androidx.glance.text.Text
@@ -49,15 +51,18 @@
 
 @Composable
 private fun WidgetLayoutCollapsed(data: GalleryTemplateData) {
-    Column(
-        modifier = GlanceModifier.fillMaxSize().padding(8.dp).background(data.backgroundColor),
-    ) {
-        Row {
-            Image(provider = data.image.image, contentDescription = data.image.description)
-            Image(provider = data.image.image, contentDescription = data.image.description)
-        }
-        Text(data.title)
-        Text(data.headline)
+    val modifier = createTopLevelModifier(data, true)
+
+    Column(modifier = modifier) {
+        data.header?.let { AppWidgetTemplateHeader(it) }
+        Spacer(modifier = GlanceModifier.defaultWeight())
+        AppWidgetTextSection(
+            listOfNotNull(
+                data.mainTextBlock.text1,
+                data.mainTextBlock.text2,
+                data.mainTextBlock.text3
+            )
+        )
     }
 }
 
@@ -65,27 +70,70 @@
 @Composable
 private fun WidgetLayoutVertical(data: GalleryTemplateData) {
     Column(
-        modifier = GlanceModifier.fillMaxSize().padding(8.dp).background(data.backgroundColor),
+        modifier = GlanceModifier.fillMaxSize().padding(8.dp),
     ) {
+        Row(
+            modifier = GlanceModifier.fillMaxSize().padding(8.dp),
+            verticalAlignment = Alignment.CenterVertically
+        ) {
+            Column {
+                MainImageBlock(data)
+            }
+            Spacer(GlanceModifier.width(8.dp))
+            Column {
+                Text(data.mainTextBlock.text1.text)
+                data.mainTextBlock.text2?.let { headline ->
+                    Text(headline.text)
+                }
+            }
+            Column(verticalAlignment = Alignment.Top) {
+                MainImageBlock(data)
+            }
+        }
     }
 }
 
 @Composable
 private fun WidgetLayoutHorizontal(data: GalleryTemplateData) {
     Row(
-        modifier = GlanceModifier.fillMaxSize().padding(8.dp).background(data.backgroundColor),
+        modifier = GlanceModifier.fillMaxSize().padding(8.dp),
         verticalAlignment = Alignment.CenterVertically
     ) {
         Column {
-            Image(provider = data.image.image, contentDescription = data.image.description)
+            MainImageBlock(data)
         }
         Spacer(GlanceModifier.width(8.dp))
         Column {
-            Text(data.title)
-            Text(data.headline)
+            Text(data.mainTextBlock.text1.text)
+            data.mainTextBlock.text2?.let { headline ->
+                Text(headline.text)
+            }
         }
         Column(verticalAlignment = Alignment.Top) {
-            Image(provider = data.image.image, contentDescription = data.image.description)
+            MainImageBlock(data)
         }
     }
 }
+
+@Composable
+private fun MainImageBlock(data: GalleryTemplateData) {
+    if (data.mainImageBlock.images.isNotEmpty()) {
+        val mainImage = data.mainImageBlock.images[0]
+        Image(provider = mainImage.image, contentDescription = mainImage.description)
+    }
+}
+
+@Composable
+private fun createTopLevelModifier(
+    data: GalleryTemplateData,
+    isImmersive: Boolean = false
+): GlanceModifier {
+    var modifier = GlanceModifier
+        .fillMaxSize().padding(16.dp).background(LocalTemplateColors.current.surface)
+    if (isImmersive && data.mainImageBlock.images.isNotEmpty()) {
+        val mainImage = data.mainImageBlock.images[0]
+        modifier = modifier.background(mainImage.image, ContentScale.Crop)
+    }
+
+    return modifier
+}
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/GlanceAppWidgetTemplates.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/GlanceAppWidgetTemplates.kt
index 6060207..c355fdb 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/GlanceAppWidgetTemplates.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/GlanceAppWidgetTemplates.kt
@@ -33,12 +33,14 @@
 import androidx.glance.layout.fillMaxWidth
 import androidx.glance.layout.height
 import androidx.glance.layout.width
+import androidx.glance.template.HeaderBlock
 import androidx.glance.template.LocalTemplateColors
 import androidx.glance.template.TemplateButton
 import androidx.glance.template.TemplateImageButton
 import androidx.glance.template.TemplateImageWithDescription
 import androidx.glance.template.TemplateText
 import androidx.glance.template.TemplateTextButton
+import androidx.glance.template.TextType
 import androidx.glance.text.Text
 import androidx.glance.text.TextStyle
 
@@ -74,13 +76,14 @@
                 Spacer(modifier = GlanceModifier.width(8.dp))
             }
             val size =
-                textSize(TemplateText.Type.Title, DisplaySize.fromDpSize(LocalSize.current))
+                textSize(TextType.Title, DisplaySize.fromDpSize(LocalSize.current))
             Text(
                 modifier = GlanceModifier.defaultWeight(),
                 text = header.text,
                 style = TextStyle(
                     fontSize = size,
-                    color = LocalTemplateColors.current.onSurface),
+                    color = LocalTemplateColors.current.onSurface
+                ),
                 maxLines = 1
             )
         }
@@ -94,8 +97,23 @@
 }
 
 /**
+ * Default header template layout implementation for AppWidgets, usually displayed at the top of the
+ * glanceable in default layout implementations by [HeaderBlock].
+ *
+ * @param headerBlock The glanceable header block to display
+ */
+@Composable
+internal fun AppWidgetTemplateHeader(headerBlock: HeaderBlock) {
+    AppWidgetTemplateHeader(
+        headerBlock.icon,
+        headerBlock.text,
+        headerBlock.actionBlock?.actionButtons?.get(0)
+    )
+}
+
+/**
  * Default text section layout for AppWidgets. Displays an ordered list of text fields, styled
- * according to the [TemplateText.Type] of each field.
+ * according to the [TextType] of each field.
  *
  * @param textList the ordered list of text fields to display in the block
  */
@@ -168,37 +186,47 @@
     }
 }
 
-private fun textSize(textClass: TemplateText.Type, displaySize: DisplaySize): TextUnit =
+private fun textSize(textClass: TextType, displaySize: DisplaySize): TextUnit =
     when (textClass) {
         // TODO: Does display scale?
-        TemplateText.Type.Display -> 45.sp
-        TemplateText.Type.Title -> {
+        TextType.Display -> 45.sp
+        TextType.Title -> {
             when (displaySize) {
                 DisplaySize.Small -> 14.sp
                 DisplaySize.Medium -> 16.sp
                 DisplaySize.Large -> 22.sp
             }
         }
-        TemplateText.Type.Body -> {
+        TextType.Headline -> {
+            when (displaySize) {
+                DisplaySize.Small -> 12.sp
+                DisplaySize.Medium -> 14.sp
+                DisplaySize.Large -> 18.sp
+            }
+        }
+        TextType.Body -> {
             when (displaySize) {
                 DisplaySize.Small -> 12.sp
                 DisplaySize.Medium -> 14.sp
                 DisplaySize.Large -> 14.sp
             }
         }
-        TemplateText.Type.Label -> {
+        TextType.Label -> {
             when (displaySize) {
                 DisplaySize.Small -> 11.sp
                 DisplaySize.Medium -> 12.sp
                 DisplaySize.Large -> 14.sp
             }
         }
+        else -> 12.sp
     }
 
-private fun maxLines(textClass: TemplateText.Type): Int =
+private fun maxLines(textClass: TextType): Int =
     when (textClass) {
-        TemplateText.Type.Display -> 1
-        TemplateText.Type.Title -> 3
-        TemplateText.Type.Body -> 3
-        TemplateText.Type.Label -> 1
+        TextType.Display -> 1
+        TextType.Title -> 3
+        TextType.Body -> 3
+        TextType.Label -> 1
+        TextType.Headline -> 1
+        else -> 1
     }
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/SingleEntityTemplateLayouts.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/SingleEntityTemplateLayouts.kt
index de9c45f..27cc583 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/SingleEntityTemplateLayouts.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/SingleEntityTemplateLayouts.kt
@@ -37,6 +37,7 @@
 import androidx.glance.template.SingleEntityTemplateData
 import androidx.glance.template.TemplateMode
 import androidx.glance.template.TemplateText
+import androidx.glance.template.TextType
 
 // TODO: Define template layouts for other surfaces
 /**
@@ -141,9 +142,9 @@
     body: TemplateText? = null
 ): List<TemplateText> {
     val result = mutableListOf<TemplateText>()
-    title?.let { result.add(TemplateText(it.text, TemplateText.Type.Title)) }
-    subtitle?.let { result.add(TemplateText(it.text, TemplateText.Type.Label)) }
-    body?.let { result.add(TemplateText(it.text, TemplateText.Type.Body)) }
+    title?.let { result.add(TemplateText(it.text, TextType.Title)) }
+    subtitle?.let { result.add(TemplateText(it.text, TextType.Label)) }
+    body?.let { result.add(TemplateText(it.text, TextType.Body)) }
 
     return result
 }
diff --git a/glance/glance-wear-tiles/integration-tests/template-demos/src/main/java/androidx/glance/wear/tiles/template/demos/DemoTile.kt b/glance/glance-wear-tiles/integration-tests/template-demos/src/main/java/androidx/glance/wear/tiles/template/demos/DemoTile.kt
index 5b75fa8..7a85f81 100644
--- a/glance/glance-wear-tiles/integration-tests/template-demos/src/main/java/androidx/glance/wear/tiles/template/demos/DemoTile.kt
+++ b/glance/glance-wear-tiles/integration-tests/template-demos/src/main/java/androidx/glance/wear/tiles/template/demos/DemoTile.kt
@@ -18,10 +18,11 @@
 
 import androidx.compose.runtime.Composable
 import androidx.glance.ImageProvider
-import androidx.glance.wear.tiles.GlanceTileService
 import androidx.glance.template.SingleEntityTemplateData
 import androidx.glance.template.TemplateImageWithDescription
 import androidx.glance.template.TemplateText
+import androidx.glance.template.TextType
+import androidx.glance.wear.tiles.GlanceTileService
 import androidx.glance.wear.tiles.template.SingleEntityTemplate
 
 /** Simple demo tile, displays [SingleEntityTemplate]  */
@@ -31,14 +32,14 @@
     override fun Content() {
         SingleEntityTemplate(
             SingleEntityTemplateData(
-                header = TemplateText("Single Entity Demo", TemplateText.Type.Title),
+                header = TemplateText("Single Entity Demo", TextType.Title),
                 headerIcon = TemplateImageWithDescription(
                     ImageProvider(R.drawable.compose),
                     "image"
                 ),
-                text1 = TemplateText("Title", TemplateText.Type.Title),
-                text2 = TemplateText("Subtitle", TemplateText.Type.Label),
-                text3 = TemplateText("Here's the body", TemplateText.Type.Body),
+                text1 = TemplateText("Title", TextType.Title),
+                text2 = TemplateText("Subtitle", TextType.Label),
+                text3 = TemplateText("Here's the body", TextType.Body),
                 image = TemplateImageWithDescription(ImageProvider(R.drawable.compose), "image"),
             )
         )
diff --git a/glance/glance-wear-tiles/src/androidMain/kotlin/androidx/glance/wear/tiles/template/SingleEntityTemplateLayouts.kt b/glance/glance-wear-tiles/src/androidMain/kotlin/androidx/glance/wear/tiles/template/SingleEntityTemplateLayouts.kt
index 252e254..10d131d 100644
--- a/glance/glance-wear-tiles/src/androidMain/kotlin/androidx/glance/wear/tiles/template/SingleEntityTemplateLayouts.kt
+++ b/glance/glance-wear-tiles/src/androidMain/kotlin/androidx/glance/wear/tiles/template/SingleEntityTemplateLayouts.kt
@@ -37,6 +37,7 @@
 import androidx.glance.template.SingleEntityTemplateData
 import androidx.glance.template.TemplateImageWithDescription
 import androidx.glance.template.TemplateText
+import androidx.glance.template.TextType
 import androidx.glance.text.Text
 import androidx.glance.text.TextAlign
 import androidx.glance.text.TextStyle
@@ -117,7 +118,7 @@
                 item.text,
                 style = TextStyle(
                     color = ColorProvider(Color.White),
-                    fontSize = if (item.type == TemplateText.Type.Title) 24.sp else 16.sp,
+                    fontSize = if (item.type == TextType.Title) 24.sp else 16.sp,
                     textAlign = TextAlign.Center)
             )
         }
@@ -130,9 +131,9 @@
     body: TemplateText? = null
 ): List<TemplateText> {
     val result = mutableListOf<TemplateText>()
-    title?.let { result.add(TemplateText(it.text, TemplateText.Type.Title)) }
-    subtitle?.let { result.add(TemplateText(it.text, TemplateText.Type.Label)) }
-    body?.let { result.add(TemplateText(it.text, TemplateText.Type.Body)) }
+    title?.let { result.add(TemplateText(it.text, TextType.Title)) }
+    subtitle?.let { result.add(TemplateText(it.text, TextType.Label)) }
+    body?.let { result.add(TemplateText(it.text, TextType.Body)) }
 
     return result
 }
diff --git a/glance/glance/api/current.txt b/glance/glance/api/current.txt
index bac023a..8dbc0bb 100644
--- a/glance/glance/api/current.txt
+++ b/glance/glance/api/current.txt
@@ -410,6 +410,42 @@
 
 package androidx.glance.template {
 
+  public final class ActionBlock {
+    ctor public ActionBlock(optional java.util.List<? extends androidx.glance.template.TemplateButton> actionButtons, optional int type);
+    method public java.util.List<androidx.glance.template.TemplateButton> getActionButtons();
+    method public int getType();
+    property public final java.util.List<androidx.glance.template.TemplateButton> actionButtons;
+    property public final int type;
+  }
+
+  @kotlin.jvm.JvmInline public final value class AspectRatio {
+    field public static final androidx.glance.template.AspectRatio.Companion Companion;
+  }
+
+  public static final class AspectRatio.Companion {
+    method public int getRatio16x9();
+    method public int getRatio1x1();
+    method public int getRatio2x3();
+    property public final int Ratio16x9;
+    property public final int Ratio1x1;
+    property public final int Ratio2x3;
+  }
+
+  @kotlin.jvm.JvmInline public final value class ButtonType {
+    field public static final androidx.glance.template.ButtonType.Companion Companion;
+  }
+
+  public static final class ButtonType.Companion {
+    method public int getFab();
+    method public int getIcon();
+    method public int getText();
+    method public int getTextIcon();
+    property public final int Fab;
+    property public final int Icon;
+    property public final int Text;
+    property public final int TextIcon;
+  }
+
   public final class CompositionLocalsKt {
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.glance.color.ColorProviders> getLocalTemplateColors();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.glance.template.TemplateMode> getLocalTemplateMode();
@@ -436,19 +472,52 @@
   }
 
   public final class GalleryTemplateData {
-    ctor public GalleryTemplateData(String header, String title, String headline, androidx.glance.template.TemplateImageWithDescription image, androidx.glance.template.TemplateImageWithDescription logo, androidx.glance.unit.ColorProvider backgroundColor);
-    method public androidx.glance.unit.ColorProvider getBackgroundColor();
-    method public String getHeader();
-    method public String getHeadline();
-    method public androidx.glance.template.TemplateImageWithDescription getImage();
-    method public androidx.glance.template.TemplateImageWithDescription getLogo();
-    method public String getTitle();
-    property public final androidx.glance.unit.ColorProvider backgroundColor;
-    property public final String header;
-    property public final String headline;
-    property public final androidx.glance.template.TemplateImageWithDescription image;
-    property public final androidx.glance.template.TemplateImageWithDescription logo;
-    property public final String title;
+    ctor public GalleryTemplateData(optional androidx.glance.template.HeaderBlock? header, androidx.glance.template.TextBlock mainTextBlock, androidx.glance.template.ImageBlock mainImageBlock, optional androidx.glance.template.ActionBlock? mainActionBlock, androidx.glance.template.ImageBlock galleryImageBlock);
+    method public androidx.glance.template.ImageBlock getGalleryImageBlock();
+    method public androidx.glance.template.HeaderBlock? getHeader();
+    method public androidx.glance.template.ActionBlock? getMainActionBlock();
+    method public androidx.glance.template.ImageBlock getMainImageBlock();
+    method public androidx.glance.template.TextBlock getMainTextBlock();
+    property public final androidx.glance.template.ImageBlock galleryImageBlock;
+    property public final androidx.glance.template.HeaderBlock? header;
+    property public final androidx.glance.template.ActionBlock? mainActionBlock;
+    property public final androidx.glance.template.ImageBlock mainImageBlock;
+    property public final androidx.glance.template.TextBlock mainTextBlock;
+  }
+
+  public final class HeaderBlock {
+    ctor public HeaderBlock(androidx.glance.template.TemplateText text, optional androidx.glance.template.TemplateImageWithDescription? icon, optional androidx.glance.template.ActionBlock? actionBlock);
+    method public androidx.glance.template.ActionBlock? getActionBlock();
+    method public androidx.glance.template.TemplateImageWithDescription? getIcon();
+    method public androidx.glance.template.TemplateText getText();
+    property public final androidx.glance.template.ActionBlock? actionBlock;
+    property public final androidx.glance.template.TemplateImageWithDescription? icon;
+    property public final androidx.glance.template.TemplateText text;
+  }
+
+  public final class ImageBlock {
+    ctor public ImageBlock(optional java.util.List<androidx.glance.template.TemplateImageWithDescription> images, optional int aspectRatio, optional int size, optional int priority);
+    method public int getAspectRatio();
+    method public java.util.List<androidx.glance.template.TemplateImageWithDescription> getImages();
+    method public int getPriority();
+    method public int getSize();
+    property public final int aspectRatio;
+    property public final java.util.List<androidx.glance.template.TemplateImageWithDescription> images;
+    property public final int priority;
+    property public final int size;
+  }
+
+  @kotlin.jvm.JvmInline public final value class ImageSize {
+    field public static final androidx.glance.template.ImageSize.Companion Companion;
+  }
+
+  public static final class ImageSize.Companion {
+    method public int getLarge();
+    method public int getMedium();
+    method public int getSmall();
+    property public final int Large;
+    property public final int Medium;
+    property public final int Small;
   }
 
   @kotlin.jvm.JvmInline public final value class ListStyle {
@@ -546,20 +615,11 @@
   }
 
   public final class TemplateText {
-    ctor public TemplateText(String text, androidx.glance.template.TemplateText.Type type);
+    ctor public TemplateText(String text, optional int type);
     method public String getText();
-    method public androidx.glance.template.TemplateText.Type getType();
+    method public int getType();
     property public final String text;
-    property public final androidx.glance.template.TemplateText.Type type;
-  }
-
-  public enum TemplateText.Type {
-    method public static androidx.glance.template.TemplateText.Type valueOf(String name) throws java.lang.IllegalArgumentException;
-    method public static androidx.glance.template.TemplateText.Type[] values();
-    enum_constant public static final androidx.glance.template.TemplateText.Type Body;
-    enum_constant public static final androidx.glance.template.TemplateText.Type Display;
-    enum_constant public static final androidx.glance.template.TemplateText.Type Label;
-    enum_constant public static final androidx.glance.template.TemplateText.Type Title;
+    property public final int type;
   }
 
   public final class TemplateTextButton extends androidx.glance.template.TemplateButton {
@@ -568,6 +628,35 @@
     property public final String text;
   }
 
+  public final class TextBlock {
+    ctor public TextBlock(androidx.glance.template.TemplateText text1, optional androidx.glance.template.TemplateText? text2, optional androidx.glance.template.TemplateText? text3, optional int priority);
+    method public int getPriority();
+    method public androidx.glance.template.TemplateText getText1();
+    method public androidx.glance.template.TemplateText? getText2();
+    method public androidx.glance.template.TemplateText? getText3();
+    property public final int priority;
+    property public final androidx.glance.template.TemplateText text1;
+    property public final androidx.glance.template.TemplateText? text2;
+    property public final androidx.glance.template.TemplateText? text3;
+  }
+
+  @kotlin.jvm.JvmInline public final value class TextType {
+    field public static final androidx.glance.template.TextType.Companion Companion;
+  }
+
+  public static final class TextType.Companion {
+    method public int getBody();
+    method public int getDisplay();
+    method public int getHeadline();
+    method public int getLabel();
+    method public int getTitle();
+    property public final int Body;
+    property public final int Display;
+    property public final int Headline;
+    property public final int Label;
+    property public final int Title;
+  }
+
 }
 
 package androidx.glance.text {
diff --git a/glance/glance/api/public_plus_experimental_current.txt b/glance/glance/api/public_plus_experimental_current.txt
index bac023a..8dbc0bb 100644
--- a/glance/glance/api/public_plus_experimental_current.txt
+++ b/glance/glance/api/public_plus_experimental_current.txt
@@ -410,6 +410,42 @@
 
 package androidx.glance.template {
 
+  public final class ActionBlock {
+    ctor public ActionBlock(optional java.util.List<? extends androidx.glance.template.TemplateButton> actionButtons, optional int type);
+    method public java.util.List<androidx.glance.template.TemplateButton> getActionButtons();
+    method public int getType();
+    property public final java.util.List<androidx.glance.template.TemplateButton> actionButtons;
+    property public final int type;
+  }
+
+  @kotlin.jvm.JvmInline public final value class AspectRatio {
+    field public static final androidx.glance.template.AspectRatio.Companion Companion;
+  }
+
+  public static final class AspectRatio.Companion {
+    method public int getRatio16x9();
+    method public int getRatio1x1();
+    method public int getRatio2x3();
+    property public final int Ratio16x9;
+    property public final int Ratio1x1;
+    property public final int Ratio2x3;
+  }
+
+  @kotlin.jvm.JvmInline public final value class ButtonType {
+    field public static final androidx.glance.template.ButtonType.Companion Companion;
+  }
+
+  public static final class ButtonType.Companion {
+    method public int getFab();
+    method public int getIcon();
+    method public int getText();
+    method public int getTextIcon();
+    property public final int Fab;
+    property public final int Icon;
+    property public final int Text;
+    property public final int TextIcon;
+  }
+
   public final class CompositionLocalsKt {
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.glance.color.ColorProviders> getLocalTemplateColors();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.glance.template.TemplateMode> getLocalTemplateMode();
@@ -436,19 +472,52 @@
   }
 
   public final class GalleryTemplateData {
-    ctor public GalleryTemplateData(String header, String title, String headline, androidx.glance.template.TemplateImageWithDescription image, androidx.glance.template.TemplateImageWithDescription logo, androidx.glance.unit.ColorProvider backgroundColor);
-    method public androidx.glance.unit.ColorProvider getBackgroundColor();
-    method public String getHeader();
-    method public String getHeadline();
-    method public androidx.glance.template.TemplateImageWithDescription getImage();
-    method public androidx.glance.template.TemplateImageWithDescription getLogo();
-    method public String getTitle();
-    property public final androidx.glance.unit.ColorProvider backgroundColor;
-    property public final String header;
-    property public final String headline;
-    property public final androidx.glance.template.TemplateImageWithDescription image;
-    property public final androidx.glance.template.TemplateImageWithDescription logo;
-    property public final String title;
+    ctor public GalleryTemplateData(optional androidx.glance.template.HeaderBlock? header, androidx.glance.template.TextBlock mainTextBlock, androidx.glance.template.ImageBlock mainImageBlock, optional androidx.glance.template.ActionBlock? mainActionBlock, androidx.glance.template.ImageBlock galleryImageBlock);
+    method public androidx.glance.template.ImageBlock getGalleryImageBlock();
+    method public androidx.glance.template.HeaderBlock? getHeader();
+    method public androidx.glance.template.ActionBlock? getMainActionBlock();
+    method public androidx.glance.template.ImageBlock getMainImageBlock();
+    method public androidx.glance.template.TextBlock getMainTextBlock();
+    property public final androidx.glance.template.ImageBlock galleryImageBlock;
+    property public final androidx.glance.template.HeaderBlock? header;
+    property public final androidx.glance.template.ActionBlock? mainActionBlock;
+    property public final androidx.glance.template.ImageBlock mainImageBlock;
+    property public final androidx.glance.template.TextBlock mainTextBlock;
+  }
+
+  public final class HeaderBlock {
+    ctor public HeaderBlock(androidx.glance.template.TemplateText text, optional androidx.glance.template.TemplateImageWithDescription? icon, optional androidx.glance.template.ActionBlock? actionBlock);
+    method public androidx.glance.template.ActionBlock? getActionBlock();
+    method public androidx.glance.template.TemplateImageWithDescription? getIcon();
+    method public androidx.glance.template.TemplateText getText();
+    property public final androidx.glance.template.ActionBlock? actionBlock;
+    property public final androidx.glance.template.TemplateImageWithDescription? icon;
+    property public final androidx.glance.template.TemplateText text;
+  }
+
+  public final class ImageBlock {
+    ctor public ImageBlock(optional java.util.List<androidx.glance.template.TemplateImageWithDescription> images, optional int aspectRatio, optional int size, optional int priority);
+    method public int getAspectRatio();
+    method public java.util.List<androidx.glance.template.TemplateImageWithDescription> getImages();
+    method public int getPriority();
+    method public int getSize();
+    property public final int aspectRatio;
+    property public final java.util.List<androidx.glance.template.TemplateImageWithDescription> images;
+    property public final int priority;
+    property public final int size;
+  }
+
+  @kotlin.jvm.JvmInline public final value class ImageSize {
+    field public static final androidx.glance.template.ImageSize.Companion Companion;
+  }
+
+  public static final class ImageSize.Companion {
+    method public int getLarge();
+    method public int getMedium();
+    method public int getSmall();
+    property public final int Large;
+    property public final int Medium;
+    property public final int Small;
   }
 
   @kotlin.jvm.JvmInline public final value class ListStyle {
@@ -546,20 +615,11 @@
   }
 
   public final class TemplateText {
-    ctor public TemplateText(String text, androidx.glance.template.TemplateText.Type type);
+    ctor public TemplateText(String text, optional int type);
     method public String getText();
-    method public androidx.glance.template.TemplateText.Type getType();
+    method public int getType();
     property public final String text;
-    property public final androidx.glance.template.TemplateText.Type type;
-  }
-
-  public enum TemplateText.Type {
-    method public static androidx.glance.template.TemplateText.Type valueOf(String name) throws java.lang.IllegalArgumentException;
-    method public static androidx.glance.template.TemplateText.Type[] values();
-    enum_constant public static final androidx.glance.template.TemplateText.Type Body;
-    enum_constant public static final androidx.glance.template.TemplateText.Type Display;
-    enum_constant public static final androidx.glance.template.TemplateText.Type Label;
-    enum_constant public static final androidx.glance.template.TemplateText.Type Title;
+    property public final int type;
   }
 
   public final class TemplateTextButton extends androidx.glance.template.TemplateButton {
@@ -568,6 +628,35 @@
     property public final String text;
   }
 
+  public final class TextBlock {
+    ctor public TextBlock(androidx.glance.template.TemplateText text1, optional androidx.glance.template.TemplateText? text2, optional androidx.glance.template.TemplateText? text3, optional int priority);
+    method public int getPriority();
+    method public androidx.glance.template.TemplateText getText1();
+    method public androidx.glance.template.TemplateText? getText2();
+    method public androidx.glance.template.TemplateText? getText3();
+    property public final int priority;
+    property public final androidx.glance.template.TemplateText text1;
+    property public final androidx.glance.template.TemplateText? text2;
+    property public final androidx.glance.template.TemplateText? text3;
+  }
+
+  @kotlin.jvm.JvmInline public final value class TextType {
+    field public static final androidx.glance.template.TextType.Companion Companion;
+  }
+
+  public static final class TextType.Companion {
+    method public int getBody();
+    method public int getDisplay();
+    method public int getHeadline();
+    method public int getLabel();
+    method public int getTitle();
+    property public final int Body;
+    property public final int Display;
+    property public final int Headline;
+    property public final int Label;
+    property public final int Title;
+  }
+
 }
 
 package androidx.glance.text {
diff --git a/glance/glance/api/restricted_current.txt b/glance/glance/api/restricted_current.txt
index bac023a..8dbc0bb 100644
--- a/glance/glance/api/restricted_current.txt
+++ b/glance/glance/api/restricted_current.txt
@@ -410,6 +410,42 @@
 
 package androidx.glance.template {
 
+  public final class ActionBlock {
+    ctor public ActionBlock(optional java.util.List<? extends androidx.glance.template.TemplateButton> actionButtons, optional int type);
+    method public java.util.List<androidx.glance.template.TemplateButton> getActionButtons();
+    method public int getType();
+    property public final java.util.List<androidx.glance.template.TemplateButton> actionButtons;
+    property public final int type;
+  }
+
+  @kotlin.jvm.JvmInline public final value class AspectRatio {
+    field public static final androidx.glance.template.AspectRatio.Companion Companion;
+  }
+
+  public static final class AspectRatio.Companion {
+    method public int getRatio16x9();
+    method public int getRatio1x1();
+    method public int getRatio2x3();
+    property public final int Ratio16x9;
+    property public final int Ratio1x1;
+    property public final int Ratio2x3;
+  }
+
+  @kotlin.jvm.JvmInline public final value class ButtonType {
+    field public static final androidx.glance.template.ButtonType.Companion Companion;
+  }
+
+  public static final class ButtonType.Companion {
+    method public int getFab();
+    method public int getIcon();
+    method public int getText();
+    method public int getTextIcon();
+    property public final int Fab;
+    property public final int Icon;
+    property public final int Text;
+    property public final int TextIcon;
+  }
+
   public final class CompositionLocalsKt {
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.glance.color.ColorProviders> getLocalTemplateColors();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.glance.template.TemplateMode> getLocalTemplateMode();
@@ -436,19 +472,52 @@
   }
 
   public final class GalleryTemplateData {
-    ctor public GalleryTemplateData(String header, String title, String headline, androidx.glance.template.TemplateImageWithDescription image, androidx.glance.template.TemplateImageWithDescription logo, androidx.glance.unit.ColorProvider backgroundColor);
-    method public androidx.glance.unit.ColorProvider getBackgroundColor();
-    method public String getHeader();
-    method public String getHeadline();
-    method public androidx.glance.template.TemplateImageWithDescription getImage();
-    method public androidx.glance.template.TemplateImageWithDescription getLogo();
-    method public String getTitle();
-    property public final androidx.glance.unit.ColorProvider backgroundColor;
-    property public final String header;
-    property public final String headline;
-    property public final androidx.glance.template.TemplateImageWithDescription image;
-    property public final androidx.glance.template.TemplateImageWithDescription logo;
-    property public final String title;
+    ctor public GalleryTemplateData(optional androidx.glance.template.HeaderBlock? header, androidx.glance.template.TextBlock mainTextBlock, androidx.glance.template.ImageBlock mainImageBlock, optional androidx.glance.template.ActionBlock? mainActionBlock, androidx.glance.template.ImageBlock galleryImageBlock);
+    method public androidx.glance.template.ImageBlock getGalleryImageBlock();
+    method public androidx.glance.template.HeaderBlock? getHeader();
+    method public androidx.glance.template.ActionBlock? getMainActionBlock();
+    method public androidx.glance.template.ImageBlock getMainImageBlock();
+    method public androidx.glance.template.TextBlock getMainTextBlock();
+    property public final androidx.glance.template.ImageBlock galleryImageBlock;
+    property public final androidx.glance.template.HeaderBlock? header;
+    property public final androidx.glance.template.ActionBlock? mainActionBlock;
+    property public final androidx.glance.template.ImageBlock mainImageBlock;
+    property public final androidx.glance.template.TextBlock mainTextBlock;
+  }
+
+  public final class HeaderBlock {
+    ctor public HeaderBlock(androidx.glance.template.TemplateText text, optional androidx.glance.template.TemplateImageWithDescription? icon, optional androidx.glance.template.ActionBlock? actionBlock);
+    method public androidx.glance.template.ActionBlock? getActionBlock();
+    method public androidx.glance.template.TemplateImageWithDescription? getIcon();
+    method public androidx.glance.template.TemplateText getText();
+    property public final androidx.glance.template.ActionBlock? actionBlock;
+    property public final androidx.glance.template.TemplateImageWithDescription? icon;
+    property public final androidx.glance.template.TemplateText text;
+  }
+
+  public final class ImageBlock {
+    ctor public ImageBlock(optional java.util.List<androidx.glance.template.TemplateImageWithDescription> images, optional int aspectRatio, optional int size, optional int priority);
+    method public int getAspectRatio();
+    method public java.util.List<androidx.glance.template.TemplateImageWithDescription> getImages();
+    method public int getPriority();
+    method public int getSize();
+    property public final int aspectRatio;
+    property public final java.util.List<androidx.glance.template.TemplateImageWithDescription> images;
+    property public final int priority;
+    property public final int size;
+  }
+
+  @kotlin.jvm.JvmInline public final value class ImageSize {
+    field public static final androidx.glance.template.ImageSize.Companion Companion;
+  }
+
+  public static final class ImageSize.Companion {
+    method public int getLarge();
+    method public int getMedium();
+    method public int getSmall();
+    property public final int Large;
+    property public final int Medium;
+    property public final int Small;
   }
 
   @kotlin.jvm.JvmInline public final value class ListStyle {
@@ -546,20 +615,11 @@
   }
 
   public final class TemplateText {
-    ctor public TemplateText(String text, androidx.glance.template.TemplateText.Type type);
+    ctor public TemplateText(String text, optional int type);
     method public String getText();
-    method public androidx.glance.template.TemplateText.Type getType();
+    method public int getType();
     property public final String text;
-    property public final androidx.glance.template.TemplateText.Type type;
-  }
-
-  public enum TemplateText.Type {
-    method public static androidx.glance.template.TemplateText.Type valueOf(String name) throws java.lang.IllegalArgumentException;
-    method public static androidx.glance.template.TemplateText.Type[] values();
-    enum_constant public static final androidx.glance.template.TemplateText.Type Body;
-    enum_constant public static final androidx.glance.template.TemplateText.Type Display;
-    enum_constant public static final androidx.glance.template.TemplateText.Type Label;
-    enum_constant public static final androidx.glance.template.TemplateText.Type Title;
+    property public final int type;
   }
 
   public final class TemplateTextButton extends androidx.glance.template.TemplateButton {
@@ -568,6 +628,35 @@
     property public final String text;
   }
 
+  public final class TextBlock {
+    ctor public TextBlock(androidx.glance.template.TemplateText text1, optional androidx.glance.template.TemplateText? text2, optional androidx.glance.template.TemplateText? text3, optional int priority);
+    method public int getPriority();
+    method public androidx.glance.template.TemplateText getText1();
+    method public androidx.glance.template.TemplateText? getText2();
+    method public androidx.glance.template.TemplateText? getText3();
+    property public final int priority;
+    property public final androidx.glance.template.TemplateText text1;
+    property public final androidx.glance.template.TemplateText? text2;
+    property public final androidx.glance.template.TemplateText? text3;
+  }
+
+  @kotlin.jvm.JvmInline public final value class TextType {
+    field public static final androidx.glance.template.TextType.Companion Companion;
+  }
+
+  public static final class TextType.Companion {
+    method public int getBody();
+    method public int getDisplay();
+    method public int getHeadline();
+    method public int getLabel();
+    method public int getTitle();
+    property public final int Body;
+    property public final int Display;
+    property public final int Headline;
+    property public final int Label;
+    property public final int Title;
+  }
+
 }
 
 package androidx.glance.text {
diff --git a/glance/glance/src/androidMain/kotlin/androidx/glance/template/GalleryTemplateData.kt b/glance/glance/src/androidMain/kotlin/androidx/glance/template/GalleryTemplateData.kt
index db61ba0..381b851 100644
--- a/glance/glance/src/androidMain/kotlin/androidx/glance/template/GalleryTemplateData.kt
+++ b/glance/glance/src/androidMain/kotlin/androidx/glance/template/GalleryTemplateData.kt
@@ -16,26 +16,31 @@
 
 package androidx.glance.template
 
-import androidx.glance.unit.ColorProvider
-
 /**
  * The semantic data required to build Gallery Template layouts
  *
- * @param header header of the template
- * @param title title of the template
- * @param headline headline of the template
- * @param image image of the template
- * @param logo logo of the template
- * @param backgroundColor The background color to apply to the template
+ * @param header The header of the template.
+ * @param mainTextBlock The head block for title, body, and other texts of the main gallery object.
+ * @param mainImageBlock The head block for an image of the main gallery object.
+ * @param mainActionBlock The head block for a list of action buttons for the main gallery object.
+ * @param galleryImageBlock The gallery block for a list of gallery images.
  */
 class GalleryTemplateData(
-    val header: String,
-    val title: String,
-    val headline: String,
-    val image: TemplateImageWithDescription,
-    val logo: TemplateImageWithDescription,
-    val backgroundColor: ColorProvider,
+    val header: HeaderBlock? = null,
+    val mainTextBlock: TextBlock,
+    val mainImageBlock: ImageBlock,
+    val mainActionBlock: ActionBlock? = null,
+    val galleryImageBlock: ImageBlock,
 ) {
+    override fun hashCode(): Int {
+        var result = mainTextBlock.hashCode()
+        result = 31 * result + (header?.hashCode() ?: 0)
+        result = 31 * result + mainImageBlock.hashCode()
+        result = 31 * result + (mainActionBlock?.hashCode() ?: 0)
+        result = 31 * result + galleryImageBlock.hashCode()
+        return result
+    }
+
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
         if (javaClass != other?.javaClass) return false
@@ -43,22 +48,11 @@
         other as GalleryTemplateData
 
         if (header != other.header) return false
-        if (title != other.title) return false
-        if (headline != other.headline) return false
-        if (image != other.image) return false
-        if (logo != other.logo) return false
-        if (backgroundColor != other.backgroundColor) return false
+        if (mainTextBlock != other.mainTextBlock) return false
+        if (mainImageBlock != other.mainImageBlock) return false
+        if (mainActionBlock != other.mainActionBlock) return false
+        if (galleryImageBlock != other.galleryImageBlock) return false
 
         return true
     }
-
-    override fun hashCode(): Int {
-        var result = header.hashCode()
-        result = 31 * result + title.hashCode()
-        result = 31 * result + headline.hashCode()
-        result = 31 * result + image.hashCode()
-        result = 31 * result + logo.hashCode()
-        result = 31 * result + backgroundColor.hashCode()
-        return result
-    }
 }
diff --git a/glance/glance/src/androidMain/kotlin/androidx/glance/template/GlanceTemplate.kt b/glance/glance/src/androidMain/kotlin/androidx/glance/template/GlanceTemplate.kt
index d4825c3..04d38a3 100644
--- a/glance/glance/src/androidMain/kotlin/androidx/glance/template/GlanceTemplate.kt
+++ b/glance/glance/src/androidMain/kotlin/androidx/glance/template/GlanceTemplate.kt
@@ -16,10 +16,10 @@
 
 package androidx.glance.template
 
-import androidx.glance.action.Action
-import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
 import androidx.glance.ImageProvider
+import androidx.glance.action.Action
 
 // TODO: Expand display context to include features other than orientation
 /** The glanceable display orientation */
@@ -32,10 +32,10 @@
 /**
  * Contains the information required to display a string on a template.
  *
- * @param text string to be displayed
- * @param type the [Type] of the item, used for styling
+ * @param text The string to be displayed.
+ * @param type The [TextType] of the item, used for styling. Default to [TextType.Title].
  */
-class TemplateText(val text: String, val type: Type) {
+class TemplateText(val text: String, val type: TextType = TextType.Title) {
 
     override fun hashCode(): Int {
         var result = text.hashCode()
@@ -54,17 +54,6 @@
 
         return true
     }
-
-    /**
-     * The text types that can be used with templates. Types are set on [TemplateText] items and
-     * can be used by templates to determine text styling.
-     */
-    enum class Type {
-        Display,
-        Title,
-        Label,
-        Body
-    }
 }
 
 /**
@@ -95,9 +84,9 @@
 }
 
 /**
- * Contains the information required to display a button on a template.
+ * Base class for a button taking an [Action] without display oriented information.
  *
- * @param action The onClick action
+ * @param action The action to take when this button is clicked.
  */
 sealed class TemplateButton(val action: Action) {
 
@@ -151,3 +140,252 @@
         return image == (other as TemplateImageButton).image
     }
 }
+
+/**
+ * A block of text with up to three different [TextType] of text lines that are displayed by the
+ * text index order (for example, text1 is displayed first). The block also has a priority number
+ * relative to other blocks such as an [ImageBlock]. Lower numbered block has higher priority to be
+ * displayed first.
+ *
+ * @param text1 The text displayed first within the block.
+ * @param text2 The text displayed second within the block.
+ * @param text3 The text displayed third  within the block.
+ * @param priority The display priority number relative to other blocks. Default to the highest: 0.
+ */
+class TextBlock(
+    val text1: TemplateText,
+    val text2: TemplateText? = null,
+    val text3: TemplateText? = null,
+    val priority: Int = 0,
+) {
+    override fun hashCode(): Int {
+        var result = text1.hashCode()
+        result = 31 * result + (text2?.hashCode() ?: 0)
+        result = 31 * result + (text3?.hashCode() ?: 0)
+        result = 31 * result + priority.hashCode()
+        return result
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (javaClass != other?.javaClass) return false
+
+        other as TextBlock
+
+        if (text1 != other.text1) return false
+        if (text2 != other.text2) return false
+        if (text3 != other.text3) return false
+        if (priority != other.priority) return false
+
+        return true
+    }
+}
+
+/**
+ * A block of image sequence by certain size and aspect ratio preferences and display priority
+ * relative to other blocks such as a [TextBlock].
+ *
+ * @param images The sequence of images or just one image for display. Default to empty list.
+ * @param aspectRatio The preferred aspect ratio of the images. Default to [AspectRatio.Ratio1x1].
+ * @param size The preferred size type of the images. Default to [ImageSize.Small].
+ * @param priority The display priority number relative to other blocks such as a [TextBlock].
+ * Default to the highest priority number 0.
+ */
+class ImageBlock(
+    val images: List<TemplateImageWithDescription> = listOf(),
+    val aspectRatio: AspectRatio = AspectRatio.Ratio1x1,
+    val size: ImageSize = ImageSize.Small,
+    val priority: Int = 0,
+) {
+    override fun hashCode(): Int {
+        var result = images.hashCode()
+        result = 31 * result + aspectRatio.hashCode()
+        result = 31 * result + size.hashCode()
+        result = 31 * result + priority.hashCode()
+        return result
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (javaClass != other?.javaClass) return false
+
+        other as ImageBlock
+
+        if (images != other.images) return false
+        if (aspectRatio != other.aspectRatio) return false
+        if (size != other.size) return false
+        if (priority != other.priority) return false
+
+        return true
+    }
+}
+
+/**
+ * Block of action list of text or image buttons.
+ *
+ * @param actionButtons The list of action buttons. Default to empty list.
+ * @param type The type of action buttons. Default to [ButtonType.Icon]
+ */
+class ActionBlock(
+    val actionButtons: List<TemplateButton> = listOf(),
+    val type: ButtonType = ButtonType.Icon,
+) {
+    override fun hashCode(): Int {
+        var result = actionButtons.hashCode()
+        result = 31 * result + type.hashCode()
+        return result
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (javaClass != other?.javaClass) return false
+
+        other as ActionBlock
+
+        if (actionButtons != other.actionButtons) return false
+        if (type != other.type) return false
+
+        return true
+    }
+}
+
+/**
+ * A header for the whole template.
+ *
+ * @param text The header text.
+ * @param icon The header image icon.
+ * @param actionBlock The header action buttons.
+ */
+class HeaderBlock(
+    val text: TemplateText,
+    val icon: TemplateImageWithDescription? = null,
+    val actionBlock: ActionBlock? = null,
+) {
+    override fun hashCode(): Int {
+        var result = text.hashCode()
+        result = 31 * result + (icon?.hashCode() ?: 0)
+        result = 31 * result + (actionBlock?.hashCode() ?: 0)
+        return result
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (javaClass != other?.javaClass) return false
+
+        other as HeaderBlock
+
+        if (text != other.text) return false
+        if (icon != other.icon) return false
+        if (actionBlock != other.actionBlock) return false
+
+        return true
+    }
+}
+
+/**
+ * The aspect ratio of an image.
+ */
+@JvmInline
+value class AspectRatio private constructor(private val value: Int) {
+    companion object {
+        /**
+         * The aspect ratio of 1 x 1.
+         */
+        val Ratio1x1: AspectRatio = AspectRatio(0)
+
+        /**
+         * The aspect ratio of 16 x 9.
+         */
+        val Ratio16x9: AspectRatio = AspectRatio(1)
+
+        /**
+         * The aspect ratio of 2 x 3.
+         */
+        val Ratio2x3: AspectRatio = AspectRatio(2)
+    }
+}
+
+/**
+ * The relative image size as a hint.
+ */
+@JvmInline
+value class ImageSize private constructor(private val value: Int) {
+    companion object {
+        /**
+         * Relative small sized image.
+         */
+        val Small: ImageSize = ImageSize(0)
+
+        /**
+         * Relative medium sized image.
+         */
+        val Medium: ImageSize = ImageSize(1)
+
+        /**
+         * Relative large sized image.
+         */
+        val Large: ImageSize = ImageSize(2)
+    }
+}
+
+/**
+ * The type of button such as FAB/Icon/Text/IconText types
+ */
+@JvmInline
+value class ButtonType private constructor(private val value: Int) {
+    companion object {
+        /**
+         * FAB (Floating Action Button) type of image button.
+         */
+        val Fab: ButtonType = ButtonType(0)
+
+        /**
+         * Icon image button type.
+         */
+        val Icon: ButtonType = ButtonType(1)
+
+        /**
+         * Text button type.
+         */
+        val Text: ButtonType = ButtonType(2)
+
+        /**
+         * Button with Text and Icon type.
+         */
+        val TextIcon: ButtonType = ButtonType(3)
+    }
+}
+
+/**
+ * The text types that can be used with templates such as set in [TemplateText] items to determine
+ * text styling.
+ */
+@JvmInline
+value class TextType private constructor(private val value: Int) {
+    companion object {
+        /**
+         * The text is for display with large font size.
+         */
+        val Display: TextType = TextType(0)
+
+        /**
+         * The text is for title content with medium font size.
+         */
+        val Title: TextType = TextType(1)
+
+        /**
+         * The text is for label content with small font size.
+         */
+        val Label: TextType = TextType(2)
+
+        /**
+         * The text is for body content with small font size.
+         */
+        val Body: TextType = TextType(3)
+
+        /**
+         * The text is headline with small font size.
+         */
+        val Headline: TextType = TextType(4)
+    }
+}