Author Archives:

Agents CLI in Agent Platform: create to production in one CLI

Google Cloud has introduced the Agents CLI, a specialized tool designed to bridge the gap between local development and production-grade AI agent deployment. The CLI provides coding assistants with machine-readable access to the full Google Cloud stack, reducing context overload and token waste during the scaffolding process. By streamlining evaluation, infrastructure provisioning, and deployment into a single programmatic backbone, the tool enables developers to move from initial concept to a live service in hours rather than weeks.

What’s new in the Jetpack Compose April ’26 release

Posted by Meghan Mehta, Android Developer Relations Engineer


Today, the Jetpack Compose April ‘26 release is stable. This release contains version 1.11 of core Compose modules (see the full BOM mapping), shared element debug tools, trackpad events, and more. We also have a few experimental APIs that we’d love you to try out and give us feedback on.

To use today’s release, upgrade your Compose BOM version to:
implementation(platform("androidx.compose:compose-bom:2026.04.01"))

Changes in Compose 1.11.0

Coroutine execution in tests

We’re introducing a major update to how Compose handles test timing. Following the opt-in period announced in Compose 1.10, the v2 testing APIs are now the default, and the v1 APIs have been deprecated. The key change is a shift in the default test dispatcher. While the v1 APIs relied on UnconfinedTestDispatcher, which executed coroutines immediately, the v2 APIs use the StandardTestDispatcher. This means that when a coroutine is launched in your tests, it is now queued and does not execute until the virtual clock is advanced.

This better mimics production conditions, effectively flushing out race conditions and making your test suite significantly more robust and less flaky.

To ensure your tests align with standard coroutine behavior and to avoid future compatibility issues, we strongly recommend migrating your test suite. Check out our comprehensive  migration guide for API mappings and common fixes.

Shared element improvements and animation tooling


We’ve also added some handy visual debugging tools for shared elements and Modifier.animatedBounds. You can now see exactly what’s happening under the hood—like target bounds, animation trajectories, and how many matches are found—making it much easier to spot why a transition might not be behaving as expected. To use the new tooling, simply surround your SharedTransitionLayout with the LookaheadAnimationVisualDebugging composable.

LookaheadAnimationVisualDebugging(
    overlayColor = Color(0x4AE91E63),
    isEnabled = true,
    multipleMatchesColor = Color.Green,
    isShowKeylabelEnabled = false,
    unmatchedElementColor = Color.Red,
) {
    SharedTransitionLayout {
        CompositionLocalProvider(
            LocalSharedTransitionScope provides this,
        ) {
            // your content
        }
    }
}

Trackpad events

We’ve revamped Compose support for trackpads, like built-in laptop trackpads, attachable trackpads for tablets, or external/virtual trackpads. Basic trackpad events will now generally be considered PointerType.Mouse events, aligning mouse and trackpad behavior to better match user expectations. Previously, these trackpad events were interpreted as fake touchscreen fingers of PointerType.Touch, which led to confusing user experiences. For example, clicking and dragging with a trackpad would scroll instead of selecting. By changing the pointer type these events have in the latest release of Compose, clicking and dragging with a trackpad will no longer scroll.

We also added support for more complicated trackpad gestures as recognized by the platform since API 34, including two finger swipes and pinches. These gestures are automatically recognized by components like Modifier.scrollable and Modifier.transformable to have better behavior with trackpads.

These changes improve behavior for trackpads across built-in components, with redundant touch slop removed, a more intuitive drag-and-drop starting gesture, double-click and triple-click selection in text fields, and desktop-styled context menus in text fields.

To test trackpad behavior, there are new testing APIs with performTrackpadInput, which allow validating the behavior of your apps when being used with a trackpad. If you have custom gesture detectors, validate behavior across input types, including touchscreens, mice, trackpads, and styluses, and ensure support for mouse scroll wheels and trackpad gestures.

Before After

Composition host defaults (Compose runtime)

We introduced HostDefaultProvider, LocalHostDefaultProvider, HostDefaultKey, and ViewTreeHostDefaultKey to supply host-level services directly through compose-runtime. This removes the need for libraries to depend on compose-ui for lookups, better supporting Kotlin Multiplatform. To link these values to the composition tree, library authors can use compositionLocalWithHostDefaultOf to create a CompositionLocal that resolves defaults from the host.

Preview wrappers

Android Studio custom previews is a new feature that allows you to define exactly how the contents of a Compose preview are displayed.

By implementing the PreviewWrapperProvider interface and applying the new @PreviewWrapper annotation, you can easily inject custom logic, such as applying a specific Theme. The annotation can be applied to a function annotated with @Composable and @Preview or @MultiPreview, offering a generic, easy-to-use solution that works across preview features and significantly reduces repetitive code.

class ThemeWrapper: PreviewWrapper {

    @Composable

    override fun Wrap(content: @Composable (() -> Unit)) {

        JetsnackTheme {

            content()

        }

    }

}


@PreviewWrapperProvider(ThemeWrapper::class)

@Preview

@Composable

private fun ButtonPreview() {

    // JetsnackTheme in effect

    Button(onClick = {}) {

        Text(text = "Demo")

    }

}

Deprecations and removals

  • As announced in the Compose 1.10 blog post, we’re deprecating Modifier.onFirstVisible(). Its name often led to misconceptions, particularly within lazy layouts, where it would trigger multiple times during scrolling. We recommend migrating to Modifier.onVisibilityChanged(), which allows for more precise manual tracking of visibility states tailored to your specific use case requirements.
  • The ComposeFoundationFlags.isTextFieldDpadNavigationEnabled flag was removed because D-pad navigation for TextFields is now always enabled by default. The new behavior ensures that the D-pad events from a gamepad or a TV remote first move the cursor in the given direction. The focus can move to another element only when the cursor reaches the end of the text.

Upcoming APIs

In the upcoming Compose 1.12.0 release, the compileSdk will be upgraded to compileSdk 37, with AGP 9 and all apps and libraries that depend on Compose inheriting this requirement. We recommend keeping up to date with the latest released versions, as Compose aims to promptly adopt new compileSdks to provide access to the latest Android features. Be sure to check out the documentation here for more information on which version of AGP is supported for different API levels.

In Compose 1.11.0, the following APIs are introduced as @Experimental, and we look forward to hearing your feedback as you explore them in your apps. Note that @Experimental APIs are provided for early evaluation and feedback and may undergo significant changes or removal in future releases.

Styles (Experimental)

We are introducing a new experimental foundation API for styling. The Style API is a new paradigm for customizing visual elements of components, which has traditionally been performed with modifiers. It is designed to unlock deeper, easier customization by exposing a standard set of styleable properties with simple state-based styling and animated transitions. With this new API, we’re already seeing promising performance benefits. We plan to adopt Styles in Material components once the Style API stabilizes.

A basic example of overriding a pressed state style background:

@Composable
fun LoginButton(modifier: Modifier = Modifier) {
    Button(
        onClick = {
            // Login logic
        },
        modifier = modifier,
        style = {
            background(
                Brush.linearGradient(
                    listOf(lightPurple, lightBlue)
                )
            )
            width(75.dp)
            height(50.dp)
            textAlign(TextAlign.Center)
            externalPadding(16.dp)

            pressed {
                background(
                    Brush.linearGradient(
                        listOf(Color.Magenta, Color.Red)
                    )
                )
            }
        }
    ){
        Text(
            text = "Login",
        )
    }
}



Check out the documentation and file any bugs here.

MediaQuery (Experimental)

The new mediaQuery API provides a declarative and performant way to adapt your UI to its environment. It abstracts complex information retrieval into simple conditions within a UiMediaScope, ensuring recomposition only happens when needed.

With support for a wide range of environmental signals—from device capabilities like keyboard types and pointer precision, to contextual states like window size and posture—you can build deeply responsive experiences. Performance is baked in with derivedMediaQuery to handle high-frequency updates, while the ability to override scopes makes testing and previews seamless across hardware configurations.

Previously, to get access to certain device properties — like if a device was in tabletop mode — you’d need to write a lot of boilerplate to do so:

@Composable
fun isTabletopPosture(
    context: Context = LocalContext.current
): Boolean {
    val windowLayoutInfo by
        WindowInfoTracker
            .getOrCreate(context)
            .windowLayoutInfo(context)
            .collectAsStateWithLifecycle(null)

    return windowLayoutInfo.displayFeatures.any { displayFeature ->
        displayFeature is FoldingFeature &&
            displayFeature.state == FoldingFeature.State.HALF_OPENED &&
            displayFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
    }
}

@Composable
fun VideoPlayer() {
    if(isTabletopPosture()) {
        TabletopLayout()
    } else {
        FlatLayout()
    }
}

Now, with UIMediaQuery, you can add the mediaQuery syntax to query device properties, such as if a device is in tabletop mode:

@OptIn(ExperimentalMediaQueryApi::class)
@Composable
fun VideoPlayer() {
    if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) {
        TabletopLayout()
    } else {
        FlatLayout()
    }
}

Check out the documentation and file any bugs here.

Grid (Experimental)

Grid is a powerful new API for building complex, two-dimensional layouts in Jetpack Compose. While Row and Column are great for linear designs, Grid gives you the structural control needed for screen-level architecture and intricate components without the overhead of a scrollable list.

Grid allows you to define your layout using tracks, gaps, and cells, offering familiar sizing options like Dp, percentages, intrinsic content sizes, and flexible "Fr" units.

@OptIn(ExperimentalGridApi::class)

@Composable

fun GridExample() {

    Grid(

        config = {

            repeat(4) { column(0.25f) }

            repeat(2) { row(0.5f) }

            gap(16.dp)

        }

    ) {

        Card1(modifier = Modifier.gridItem(rowSpan = 2)

        Card2(modifier = Modifier.gridItem(colmnSpan = 3)

        Card3(modifier = Modifier.gridItem(columnSpan = 2)

        Card4()

    }

}


You can place items automatically or explicitly span them across multiple rows and columns for precision. Best of all, it’s highly adaptive—you can dynamically reconfigure your grid tracks and spans to respond to device states like tabletop mode or orientation changes, ensuring your UI looks great across form factors.


Check out the documentation and file any bugs here.

FlexBox (Experimental)

FlexBox is a layout container designed for high performance, adaptive UIs. It manages item sizing and space distribution based on available container dimensions. It handles complex tasks like wrapping (wrap) and multi-axis alignment of items (justifyContent, alignItems, alignContent). It allows items to grow (grow) or shrink (shrink) to fill the container.

@OptIn(ExperimentalFlexBoxApi::class)
fun FlexBoxWrapping(){
    FlexBox(
        config = {
            wrap(FlexWrap.Wrap)
            gap(8.dp)
        }
    ) {
        RedRoundedBox()
        BlueRoundedBox()
        GreenRoundedBox(modifier = Modifier.width(350.dp).flex { grow(1.0f) })
        OrangeRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.7f) })
        PinkRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.3f) })
    }
}





Check out the documentation and file any bugs here.

New SlotTable implementation (Experimental)

We’ve introduced a new implementation of the SlotTable, which is disabled by default in this release. SlotTable is the internal data structure that the Compose runtime uses to track the state of your composition hierarchy, track invalidations/recompositions, store remembered values, and track all metadata of the composition at runtime. This new implementation is designed to improve performance, primarily around random edits.

To try the new SlotTable, enable ComposeRuntimeFlags.isLinkBufferComposerEnabled.

Start coding today!

With so many exciting new APIs in Jetpack Compose, and many more coming up, it's never been a better time to migrate to Jetpack Compose. As always, we value your feedback and feature requests (especially on @Experimental features that are still baking) — please file them here. Happy composing!

Stable Channel Update for ChromeOS / ChromeOS Flex

The ChromeOS Stable channel is being updated to OS version 16610.44.0 (Browser version 147.0.7727.115) for most ChromeOS devices.

If you find new issues, please let us know one of the following ways:
  1. File a bug
  2. Visit our ChromeOS communities

    1. General: Chromebook Help Community

    2. Beta Specific: ChromeOS Beta Help Community

  3. Report an issue or send feedback on Chrome

  4. Interested in switching channels? Find out how.

Alon Bajayo

Google ChromeOS

Announcing v24 of the Google Ads API

Today, we’re announcing the v24 release of the Google Ads API. To use the new v24 features, you must upgrade your client libraries and client code. All the updated client libraries and code examples have been published.

Come join us for a live walkthrough of this release in our "Google Ads API Release Highlights" event on Discord, our Ads Developers YouTube Live, or our LinkedIn Live event tomorrow (April 23rd at 10a ET). This will also be recorded and posted on YouTube for those who can’t make the live events. If you have any questions or want to discuss this post, reach out to us in the #ads-api channel on Discord.

New features

Support for Conversions with Cart Data: Conversions with cart data is an extension to conversion tracking on your website or app. Using conversions with cart data, you can provide the details of products sold for each transaction, which helps you unlock advanced sales, profit reporting, and insights for your Google Ads account and campaigns, such as number of orders, average cart size, revenue and gross profit.

Google Ads API v24 adds support for this feature as follows:

  • Added a new resource CartDataSalesView that allows segmenting conversion metrics not only by the product clicked, but also by the product sold, with segments like product_sold_brand. These enable advertisers to view statistics on the products the customers actually bought after clicking ads, even if the ad was for a different product.
  • Added several “all” non-biddable metrics, which are metrics that also include the conversions your campaigns are not actively optimizing towards, for example all_cost_of_goods_sold_micros. The new metrics are added to all resources supporting corresponding biddable metrics.
  • Added the conversion_attribution_event_type segment to the ShoppingPerformanceView resource, making it selectable with cart data and other conversion metrics. This segment denotes whether the conversion is attributed to a click or to a view and it is necessary to recognize cart data stats produced by view-through conversions.

Updated features

Version v24 introduces updates to existing features that require code changes when upgrading. We cover the most important ones here; check out the release notes for the full list of changes.

Video content exclusion settings in campaigns: We simplified the ability to set video content exclusion settings on individual campaigns. This setting is available at the customer level, and applies to all the campaigns instead. These content exclusion settings are meant to give you additional control and help you exclude types of content that, while in compliance with our policies, may not fit your brand or business. See https://support.google.com/google-ads/answer/7515513 to learn more about video content exclusion settings.

Changes to AudienceInsightsService: As part of a code refactoring, we moved the InsightsAudience.topic_audience_combinations request field into the common namespace. You may need to update your import directives in some programming languages.

Changes to ReachPlanService: As part of a code refactoring, we moved the youtube_select_lineups field from the ReachPlanService.ListPlannableProducts service. Lineups are now available within the youtube_select_lineup_targeting field. YouTube Select Lineups are reservation products for eligible clients to target among the top 1% of popular channels on YouTube with the most passionate audiences in a given market. Learn more.

Changes to ContentCreatorInsightsService: As part of a code refactoring, we removed the is_brand_connect_creator field from the ContentCreatorInsightsService.GenerateCreatorInsights and ContentCreatorInsightsService.GenerateTrendingInsights services.
Users should instead look for a creator to have the CREATOR_PARTNERSHIPS option available instead in partnership_opportunities. The YouTube Creator Partnerships in Google Ads is the space where you can find YouTube creators to partner with on sponsored content and help you efficiently manage your creator partnerships. Learn more.

Changes to KeywordPlanIdeaService: To provide a more streamlined and reliable experience, we have unified our forecasting infrastructure. Google Ads API v24 introduces an updated GenerateKeywordForecastMetrics method that simplifies the planning process by focusing on the metrics that most directly impact your performance. We will share a more detailed blog post about this change in the coming days.

Changes to campaign_budget resource: We removed the ad_sub_network_type segment for the campaign_budget resource because it is incompatible with this view.

Changes to asset views: We removed the click_type segment from the ad_group_asset, campaign_asset, and customer_asset views. This change aligns with a recent product change that removed this segment from the Google Ads to avoid misrepresentation of data. You can use the click_type segmentation from the ad_group_ad resource to get details on the ad performance and the asset it was served with.

Changes to video responsive ad: VideoResponsiveAdInfo is now mutable. As part of this change, we have marked videos, business_name and logo_images as required fields in both the DemandGenVideoResponsiveAdInfo and VideoResponsiveAdInfo objects.

Changes to ShareablePreviewService: Updated ShareablePreviewService.GenerateShareablePreviews to not use partial failure anymore. Requests will throw an error if they fail for any ID. Learn more.

The following resources can help you get started:

For technical support issues, reach out to https://support.google.com/google-ads/contact/google_ads_api

Streamline User Journeys with Verified Email via Credential Manager

Posted by Niharika Arora, Senior Developer Relations Engineer and Jean-Pierre Pralle, Product Manager, Credential Manager



In the modern digital landscape, the first encounter a user has with an app is often the most critical. Yet, for decades, this initial interaction has been hindered by the friction of traditional verification methods. Today, we're excited to announce a new verified email credential issued by Google, which developers can now retrieve directly from Android’s Credential Manager Digital Credential API.

The Problem: Authentication Friction in the Modern Era

The "current era" of authentication is defined by a trade-off between security and convenience. To ensure that a user owns the email address they provide, you typically rely on One-Time Passwords (OTPs) or "magic links" sent by email or SMS.

While effective, these traditional steps introduce significant hurdles:

  • Context switching: Users must leave the app, open their inbox or messaging app, find the code, and return, a process where many potential users simply drop off.
  • Delivery issues: While Emails are free, they can be delayed or diverted to spam folders.
  • Onboarding friction: Every extra second spent in the "verification loop" is a second where a user might lose interest, directly impacting conversion rates.

The Solution: Seamless, Verified Email

Google now issues a cryptographically verified email credential directly to Android devices. This verified email credential is delivered through the Credential Manager API, which is Android's implementation of the W3C's Digital Credential API standard.

For users, this completely removes the need to manually verify their email through external channels. For developers, the API securely delivers these verified user claims for any scenario whether you are building an account creation flow, a recovery process, or a high-risk step-up authentication.

While this specific verified email address is sourced securely from the user's Google Account on their device, the underlying Digital Credentials API is issuer-agnostic. This fosters an open ecosystem, allowing any holder of a digital credential with an email claim to offer that verification to your app.

User Experience

The beauty of this API lies in its simplicity for the end user. Instead of hunting for OTP codes, the experience is integrated directly into the Android OS:

  • Initiation: The process begins when a user focuses on an email input field or taps a "Sign up" or "Recover account" button. You can also initiate the process on page load.
  • Transparency: A native Android bottom sheet appears, clearly detailing exactly what data is being requested (for example, user’s verified email address).
  • One-tap consent: The user simply taps "Agree and continue" to share the data.
  • Immediate progress: Once consent is given, the app receives the data instantly. For sign-up or account recovery flows, you can then seamlessly transition the user into passkey creation, ensuring:
    • Users do not have to enter any user information manually, as compared to the traditional username/password registration.
    • Their next login is even faster and more secure.

Use case 1. Sign up

Accelerate onboarding by fetching a verified email the moment the user taps "Sign up". We strongly recommend you pair the verified email retrieval with passkey creation, also part of the Credential Manager API:



Note: You can also fetch other unverified fields such as a user’s given name, family name, name, profile picture and the hosted domain connected with the verified email.

Use case 2. Account recovery

Eliminate the frustration of users hunting for recovery codes in their spam folders by allowing them to recover their account using the verified email securely stored on their device.



Use case 3. Re-authentication for sensitive actions

Protect sensitive user actions, such as changing settings or updating profile details, by requiring a quick re-authentication step. Instead of an OTP, you can provide a low-friction verification using the device's verified email.



Important Considerations

As you design your authentication architecture around the Digital Credentials API, keep the following details in mind:

  • Account support: For the specific email credential issued by Google, only regular consumer Google Accounts are supported (Workspace and supervised accounts are currently not supported). Keep in mind that the Credential Manager API itself is issuer-agnostic, meaning other identity providers can issue credentials with their own account support policies.
  • Other user data: Beyond email, you can request the user's given name, family name, full name, and profile picture. However, note that only the email is verified by Google.
  • Auto verify your @gmail accounts: The API provides verified emails for all consumer Google Accounts. We recommend auto-verifying @gmail.com users and routing custom domains to your existing verification flow - for example, an OTP flow. This ensures you maintain long-term access for external domains not directly managed by Google.
  • Complementary to Sign in with Google: While both the new verified email credential & Sign in with Google API provides a verified email, the choice depends on the intended user experience:
    • Use Sign in with Google when your users want to create a federated login session.
    • Use Verified Email when your users want to sign in traditionally with a username/password or passkey but want to auto-verify the email address without the manual chore of an OTP.

Conclusion and Next steps

By integrating the new verified email via Credential Manager API, you can drastically reduce onboarding friction and provide users with a more streamlined, secure authentication journey. This represents a shift toward a future where "verification" is no longer a manual chore for the user, but a seamless, integrated part of the native mobile experience.

Ready to see how this fits into your own app? To get started, update your project to the latest Credential Manager API and explore our Integration Guide. We encourage you to explore how this streamlined verification can simplify your critical user journeys from optimizing account creation, to enhancing re-authentication flows.