Skip to content

Update to the 1.4/1.6 releases of android.wear.{protolayout,tiles}#1359

Closed
ithinkihaveacat wants to merge 18 commits intoandroid:mainfrom
ithinkihaveacat:tiles-1.6-update
Closed

Update to the 1.4/1.6 releases of android.wear.{protolayout,tiles}#1359
ithinkihaveacat wants to merge 18 commits intoandroid:mainfrom
ithinkihaveacat:tiles-1.6-update

Conversation

@ithinkihaveacat
Copy link
Copy Markdown
Contributor

@ithinkihaveacat ithinkihaveacat commented Feb 25, 2026

Summary / Goal
Update Wear OS Jetpack library dependencies to their final stable releases and remove redundant Horologist dependencies from the sample app.

Motivation
The project was previously using beta/RC versions of the androidx.wear.tiles and androidx.wear.protolayout libraries. With these libraries now stable and the main sample having migrated to Material3TileService natively, we can finalize the versions, remove the unneeded Horologist abstraction, and ensure our preview assets reflect the modern Material 3 design system.

Proposed Changes

  • Library Updates: Updated androidx-wear-tiles to 1.6.0 and androidx-wear-protolayout to 1.4.0 in the version catalog.
  • Horologist Removal: Removed horologist-tiles from the WearTilesKotlin/app dependencies and deleted the associated experimental compiler opt-in flag.
  • Asset Modernization: Replaced outdated static screenshots for the MessagingTileService with fresh captures from an API 36 emulator, reflecting the new Material 3 Dynamic Colors and required header icon.
  • Resource Fixes: Replaced unresolved ?attr/colorControlNormal references in vector drawables with @android:color/white to fix resource linking errors caused by the dependency removal.

Rationale & Safety
This cleanup aligns the sample with the intended stable usage of the APIs. The removal of Horologist does not impact runtime behavior, as the main tile was already refactored to use Material3TileService.

(Note on Golden Tiles: The reference layouts in com.example.wear.tiles.golden have not been refactored yet. However, they remain functionally sound and self-contained, correctly inheriting dynamic colors via materialScopeWithResources. They will be architecturally unified in a follow-up commit.)

Verification

  • Performed a clean build (./gradlew assembleDebug) successfully.
  • Deployed the MessagingTileService to an API 36 Wear OS emulator and verified dynamic color support and layout integrity.

Also updates:
- Compose to 1.10.3
- Android Gradle Plugin to 8.13.2
- Refactor MessagingTileService to inherit from Material3TileService
- Move resource loading and tile construction into tileResponse
- Refactor tileLayout to be an extension on MaterialScope
- Remove dependency on Horologist's SuspendingTileService for this component
- Use MaterialScope.image with ProtoLayoutScope for automatic resource registration
- Simplify tileResponse to leverage the new automated system in Material3TileService
- Fix Ali's avatar URL extension (.png -> .jpg) to resolve 404 error
- Ensure contacts without avatars correctly fallback to themed initials
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @ithinkihaveacat, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request primarily focuses on upgrading the Android Wear OS Protobuf Layout and Tiles libraries to their latest beta versions (1.4 and 1.6 respectively). This update necessitates significant refactoring across the codebase, particularly in how tile services are implemented and how image resources are managed and provided. The changes aim to align the sample code with the latest best practices and API changes introduced in these new library versions, ensuring compatibility and leveraging new features for more efficient resource handling and simplified tile creation.

Highlights

  • Dependency Updates: Updated androidx-wear-tiles to 1.6.0-beta01 and androidx-wear-protolayout to 1.4.0-beta01 in gradle/libs.versions.toml.
  • API Migration for Tile Services: Migrated BaseTileService implementations to the new TileService or Material3TileService APIs, specifically changing layout and resources overrides to onTileRequest or tileResponse.
  • Resource Handling Refactor: Refactored image resource handling across all golden tile examples. This includes replacing materialScope with materialScopeWithResources, introducing ProtoLayoutScope for resource collection, and updating image references from context.resources.getResourceName(R.drawable.xyz) to imageResource(androidImageResource(R.drawable.xyz)).
  • Simplified Image Mapping: Removed explicit resources functions and addIdToImageMapping calls from most tile examples, as the new materialScopeWithResources and ProtoLayoutScope now manage resource collection more efficiently.
  • TilePreviewData Updates: Adjusted TilePreviewData constructors to align with the new API, now accepting lambda functions for onTileRequest and onTileResourceRequest.
  • Messaging Tile Service Enhancements: The MessagingTileService now extends Material3TileService and uses the tileResponse method, simplifying the tile and resource request logic. Image loading for contacts was also streamlined.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • WearTilesKotlin/app/src/debug/java/com/example/wear/tiles/golden/Alarm.kt
    • Updated imports for new ProtoLayout and Tiles APIs.
    • Replaced materialScope with materialScopeWithResources.
    • Modified layout function signature to include ProtoLayoutScope.
    • Updated image resource references to use imageResource(androidImageResource(...)).
    • Removed the resources function and related addIdToImageMapping calls.
    • Migrated AlarmTileService from BaseTileService to TileService and updated layout to onTileRequest.
  • WearTilesKotlin/app/src/debug/java/com/example/wear/tiles/golden/Calendar.kt
    • Updated imports for new ProtoLayout and Tiles APIs.
    • Replaced materialScope with materialScopeWithResources.
    • Modified layout function signature to include ProtoLayoutScope.
    • Updated image resource references to use imageResource(androidImageResource(...)).
    • Removed the resources function and related addIdToImageMapping calls.
    • Migrated Calendar1TileService and Calendar2TileService from BaseTileService to TileService and updated layout to onTileRequest.
  • WearTilesKotlin/app/src/debug/java/com/example/wear/tiles/golden/Goal.kt
    • Updated imports for new ProtoLayout and Tiles APIs.
    • Replaced materialScope with materialScopeWithResources.
    • Modified layout function signature to include ProtoLayoutScope.
    • Updated image resource references to use imageResource(androidImageResource(...)).
    • Removed the resources function and related addIdToImageMapping calls.
    • Migrated GoalTileService from BaseTileService to TileService and updated layout to onTileRequest.
  • WearTilesKotlin/app/src/debug/java/com/example/wear/tiles/golden/Hike.kt
    • Updated imports for new ProtoLayout and Tiles APIs.
    • Replaced materialScope with materialScopeWithResources.
    • Modified layout function signature to include ProtoLayoutScope.
    • Updated image resource references to use imageResource(androidImageResource(...)).
    • Removed the resources function and related addIdToImageMapping calls.
    • Migrated HikeTileService from BaseTileService to TileService and updated layout to onTileRequest.
  • WearTilesKotlin/app/src/debug/java/com/example/wear/tiles/golden/Media.kt
    • Updated imports for new ProtoLayout and Tiles APIs.
    • Replaced materialScope with materialScopeWithResources.
    • Modified layout function signature to include ProtoLayoutScope.
    • Updated image resource references to use imageResource(androidImageResource(...)).
    • Removed the resources function and related addIdToImageMapping calls.
    • Migrated MediaTileService from BaseTileService to TileService and updated layout to onTileRequest.
    • Updated Playlist data class to use @DrawableRes Int? for imageId.
  • WearTilesKotlin/app/src/debug/java/com/example/wear/tiles/golden/Meditation.kt
    • Updated imports for new ProtoLayout and Tiles APIs.
    • Replaced materialScope with materialScopeWithResources.
    • Modified listLayout function signature to include ProtoLayoutScope.
    • Updated image resource references to use imageResource(androidImageResource(...)).
    • Removed the resources function and related addIdToImageMapping calls.
    • Migrated MindfulnessTileService from BaseTileService to TileService and updated layout to onTileRequest.
    • Updated MeditationTask data class to use @DrawableRes Int for iconId.
  • WearTilesKotlin/app/src/debug/java/com/example/wear/tiles/golden/News.kt
    • Updated imports for new ProtoLayout and Tiles APIs.
    • Replaced materialScope with materialScopeWithResources.
    • Modified layout function signature to include ProtoLayoutScope.
    • Updated image resource references to use imageResource(androidImageResource(...)).
    • Removed the resources function and related addIdToImageMapping calls.
    • Migrated NewsTileService from BaseTileService to TileService and updated layout to onTileRequest.
    • Updated ArticleData and newsCard to use @DrawableRes Int for imageResourceId.
  • WearTilesKotlin/app/src/debug/java/com/example/wear/tiles/golden/Ski.kt
    • Updated imports for new ProtoLayout and Tiles APIs.
    • Replaced materialScope with materialScopeWithResources.
    • Modified layout function signature to include ProtoLayoutScope.
    • Removed the resources function.
    • Migrated SkiTileService from BaseTileService to TileService and updated layout to onTileRequest.
  • WearTilesKotlin/app/src/debug/java/com/example/wear/tiles/golden/Social.kt
    • Updated imports for new ProtoLayout and Tiles APIs.
    • Replaced materialScope with materialScopeWithResources.
    • Modified layout function signature to include ProtoLayoutScope.
    • Removed the resources function and related addIdToImageMapping calls.
    • Migrated SocialTileService* from BaseTileService to TileService and updated layout to onTileRequest.
    • Updated Contact data class to remove avatarId: String? and adjusted contactButton logic accordingly.
  • WearTilesKotlin/app/src/debug/java/com/example/wear/tiles/golden/Timer.kt
    • Updated imports for new ProtoLayout and Tiles APIs.
    • Replaced materialScope with materialScopeWithResources.
    • Modified timer1Layout and timer2Layout function signatures to include ProtoLayoutScope.
    • Updated image resource references to use imageResource(androidImageResource(...)).
    • Removed the resources function and related addIdToImageMapping calls.
    • Migrated Timer1TileService and Timer2TileService from BaseTileService to TileService and updated layout to onTileRequest.
  • WearTilesKotlin/app/src/debug/java/com/example/wear/tiles/golden/Weather.kt
    • Updated imports for new ProtoLayout and Tiles APIs.
    • Replaced materialScope with materialScopeWithResources.
    • Modified layout function signature to include ProtoLayoutScope.
    • Updated image resource references to use imageResource(androidImageResource(...)).
    • Removed the resources function and related addIdToImageMapping calls.
    • Migrated WeatherTileService from BaseTileService to TileService and updated layout to onTileRequest.
    • Updated Forecast and Conditions data classes to use @DrawableRes Int for weatherIconId.
    • Extracted weather data creation into a private helper function weatherData().
  • WearTilesKotlin/app/src/debug/java/com/example/wear/tiles/golden/Workout.kt
    • Updated imports for new ProtoLayout and Tiles APIs.
    • Replaced materialScope with materialScopeWithResources.
    • Modified layout1 and layout2 function signatures to include ProtoLayoutScope.
    • Updated image resource references to use imageResource(androidImageResource(...)).
    • Removed the resources function and related addIdToImageMapping calls.
    • Migrated WorkoutTileService1 and WorkoutTileService2 from BaseTileService to TileService and updated layout to onTileRequest.
    • Updated workoutGraphicDataCard to use @DrawableRes Int for iconId.
  • WearTilesKotlin/app/src/main/java/com/example/wear/tiles/messaging/Contact.kt
    • Updated the avatar image extension for 'Ali C' from .png to .jpg.
  • WearTilesKotlin/app/src/main/java/com/example/wear/tiles/messaging/Layout.kt
    • Updated contactButton function signature to accept an ImageResource for avatar display.
    • Modified tileLayout to be an extension function of MaterialScope and accept a map of image resources.
    • Updated TilePreviewData to use materialScope and pass the collected image resources to tileLayout.
  • WearTilesKotlin/app/src/main/java/com/example/wear/tiles/messaging/Service.kt
    • Changed the base class from SuspendingTileService to Material3TileService.
    • Replaced tileRequest and resourcesRequest methods with a single tileResponse method.
    • Simplified the logic for loading and providing image resources within the tileResponse method.
    • Removed the DEBUG_RESOURCES constant.
  • WearTilesKotlin/app/src/main/java/com/example/wear/tiles/tools/Extensions.kt
    • Added a tile extension function for MaterialScope to simplify tile creation.
    • Added a MaterialScope.image extension function and deprecated the old image function.
  • WearTilesKotlin/gradle/libs.versions.toml
    • Updated android-gradle-plugin from 8.13.1 to 8.13.2.
    • Updated compose from 1.9.4 to 1.10.3.
    • Updated androidx-wear-tiles from 1.5.0 to 1.6.0-beta01.
    • Updated androidx-wear-protolayout from 1.3.0 to 1.4.0-beta01.
Activity
  • The pull request was created by ithinkihaveacat to update Android Wear OS library versions and associated code.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the android.wear.protolayout and android.wear.tiles dependencies to new major versions and refactors the codebase to adopt the new APIs. The changes are extensive, moving from manual resource management and BaseTileService to the more integrated TileService and materialScopeWithResources. Overall, the migration is well-executed across most of the tile implementations.

However, I've identified a few critical issues. There's a bug in Calendar.kt where an image resource is hardcoded due to an incomplete migration of its data model. Additionally, messaging/Layout.kt contains a couple of errors: a call to a non-existent method setImageResource and incorrect syntax for Kotlin's associate function, both of which will prevent the code from compiling. Please address these points to ensure the migration is complete and correct.

Comment thread WearTilesKotlin/app/src/main/java/com/example/wear/tiles/messaging/Layout.kt Outdated
Comment thread WearTilesKotlin/app/src/debug/java/com/example/wear/tiles/golden/Calendar.kt Outdated
Comment thread WearTilesKotlin/app/src/main/java/com/example/wear/tiles/messaging/Layout.kt Outdated
- Update Gradle to 9.3.1
- Update Android Gradle Plugin to 9.1.0
- Update Kotlin to 2.2.10
- Add recommended build features and compatibility flags to gradle.properties
Update androidx-wear-tiles to 1.6.0 and androidx-wear-protolayout to
1.4.0. These represent the final stable releases for these
libraries.

The update was verified with a clean build and manual deployment to
an API 36 Wear OS emulator. Visual inspection confirmed that the
tile correctly adopts Material 3 dynamic colors and displays the
required branding header icon.
Resolve merge conflicts with upstream/main in libs.versions.toml,
gradle-wrapper.properties, and gradle-daemon-jvm.properties.

- Update ktlint to 1.4.0 and Kotlin to 2.3.20 in libs.versions.toml.
- Update Gradle wrapper to 9.4.1.
- Revert gradle-daemon-jvm.properties to upstream version.
- Fix build errors in app/build.gradle.kts by migrating kotlinOptions
  to compilerOptions DSL.
Remove leftover Horologist dependencies and update the messaging tile
screenshots to reflect the recent migration to Material3TileService.

- Removed `horologist-tiles` from `WearTilesKotlin/app` dependencies
  and the associated experimental compiler flag.
- Updated `tile_messaging.png` in resources and README screenshots to
  show the new Material 3 Dynamic Colors and branding header.
- Replaced `?attr/colorControlNormal` in vector drawables with white to
  fix resource linking errors caused by the dependency removal.
- Removed Horologist mentions from the README.
- Add ratchetFrom = "origin/main" to spotless configuration.
- Increase max line length to 120 in .editorconfig.
- Fix build errors in app/build.gradle.kts by adding compose runtime
  and migrating to compilerOptions DSL.
- Fix lint errors (suppressions, imports, file renaming).
- Revert Kotlin version to 2.2.10 in libs.versions.toml to fix
  compose compiler error.
- Apply formatting to files modified in this branch.
Remove implementation(libs.horologist.tiles) from app/build.gradle.kts
as it was accidentally re-added and the branch has migrated to use
Material3TileService directly.
Merge branch 'upstream/main' into tiles-1.6-update.
Resolve conflicts in app/build.gradle.kts and libs.versions.toml by:
- Removing Horologist dependency as requested.
- Keeping max versions or buildable versions.
Remove org.jetbrains.kotlin.plugin.compose and buildFeatures.compose
from app/build.gradle.kts as it is not needed for Tile layouts and
causes compilation errors in release builds with newer Kotlin versions.
Also remove the explicitly added compose runtime dependency.
- Fix non-existent setImageResource call in Layout.kt by using
  setResourceId.
- Remove unnecessary type arguments in associate in Layout.kt.
- Fix hardcoded image resource in Calendar.kt by updating Event data
  class to use @DrawableRes Int and updating call sites.
- Add missing DrawableRes import in Calendar.kt.
Replace deprecated setResourceId and custom image builder with
protoLayoutScope.basicImage in contactButton in Layout.kt.
This uses the modern API introduced in 1.4 and removes the deprecation
warning.
Run spotlessApply to fix formatting violations in Calendar.kt and
Layout.kt as reported by CI. This includes line wrapping and import
sorting.
@ithinkihaveacat
Copy link
Copy Markdown
Contributor Author

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the Wear Tiles sample to migrate from Horologist to the native Material3TileService and updates dependencies to Wear Tiles 1.6.0 and ProtoLayout 1.4.0. Key changes include transitioning to materialScopeWithResources, updating image handling with androidImageResource, and implementing a coroutine-based MessagingTileService using Coil. Feedback highlights unused variables in News.kt, a redundant build() call in Timer.kt, and a recommendation to use the idiomatic isNotEmpty() extension in Layout.kt.

Comment on lines 113 to 114
val now = LocalDateTime.of(2024, 8, 1, 0, 0).toInstant(ZoneOffset.UTC)
Clock.fixed(now, Clock.systemUTC().zone)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The LocalDateTime and Clock instances are created but never used in the preview generation. If they are not needed for the layout, they should be removed to keep the code clean.

buttonGroupItem { timerButton("25", "Mins") }
}
)
build()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The call to build() inside the column builder is redundant. The column helper function already calls build() on the Column.Builder it creates.

}
}
)
if (!row2.isEmpty()) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In Kotlin, it is more idiomatic to use isNotEmpty() instead of !isEmpty() for collection checks.

Suggested change
if (!row2.isEmpty()) {
if (row2.isNotEmpty()) {

@ithinkihaveacat
Copy link
Copy Markdown
Contributor Author

This PR is too big. Splitting; first part is #1367.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant