Skip to content

Add missing TvContractCompat.WatchNextPrograms class to TvProvider binding#1367

Draft
Copilot wants to merge 4 commits intomainfrom
copilot/add-watchnextprograms-class
Draft

Add missing TvContractCompat.WatchNextPrograms class to TvProvider binding#1367
Copilot wants to merge 4 commits intomainfrom
copilot/add-watchnextprograms-class

Conversation

Copy link
Contributor

Copilot AI commented Feb 20, 2026

TvContractCompat.WatchNextPrograms is missing from Xamarin.AndroidX.TvProvider 1.1.0.2+. The Java class exists in the AAR but is dropped during binding generation because it contains only static final fields (no constructors/methods) — the generator treats it as empty and removes it.

Changes

  • Metadata.xml (source/androidx.tvprovider/tvprovider/Transforms/Metadata.xml): Uses add-node to define TvContractCompat.WatchNextPrograms with a package-private constructor, which prevents the binding generator from dropping it. The class is completely absent from api.xml (dropped before Metadata.xml transforms run), so a full class definition is added including all fields from the Java API:
    • ContentUri (static android.net.Uri field, accessed via JNI)
    • String constants: ContentType, ContentItemType, ColumnWatchNextType, ColumnLastEngagementTimeUtcMillis
    • Int constants: WatchNextTypeContinue (0), WatchNextTypeNext (1), WatchNextTypeNew (2), WatchNextTypeWatchlist (3)
  • PublicAPI.Unshipped.txt updated automatically by build

Usage

var val = TvContractCompat.WatchNextPrograms.WatchNextTypeContinue;
var uri = TvContractCompat.WatchNextPrograms.ContentUri;
Original prompt

This section details on the original issue you should resolve

<issue_title>[Xamarin.AndroidX.TvProvider] TvContractCompat.WatchNextPrograms class is missing</issue_title>
<issue_description>### Android framework version

net9.0-android, net10.0-android

Affected platform version

.NET 9, .NET 10

Description

The TvContractCompat.WatchNextPrograms class is missing from NuGet package version 10.0.0.35 or newer

As per the api documentation, this class should be available in v1.1.0

Steps to Reproduce

  1. Create .NET Android project dotnet new android -n test.android
  2. Open test.android.csproj file
  3. Add <PackageReference Include="Xamarin.AndroidX.TvProvider" Version="1.1.0.2" /> NuGet package
  4. Build the project
  5. Open MainActivity.cs file
  6. Add variable var val = TvContractCompat.WatchNextPrograms.WatchNextTypeContinue;

Did you find any workaround?

Use version 1.0.0.34 or older

Relevant log output

```</issue_description>

## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

The class was being dropped during API generation because it only
contains static final fields with no constructors or methods. Added
a manual C# binding in Additions that provides all the constants
from the Java API including CONTENT_URI, CONTENT_TYPE, CONTENT_ITEM_TYPE,
WATCH_NEXT_TYPE_* constants, and COLUMN_* constants.

Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com>
Copilot AI changed the title [WIP] Add WatchNextPrograms class to TvContractCompat Add missing TvContractCompat.WatchNextPrograms class to TvProvider binding Feb 20, 2026
Copy link
Member

@jonathanpeppers jonathanpeppers left a comment

Choose a reason for hiding this comment

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

@copilot you should fix this via Metadata.xml instead of adding manual bindings via Additions!

Replace manual C# Additions with Metadata.xml remove-node/add-node to
define TvContractCompat.WatchNextPrograms. The binding generator drops
constants-only classes during processing; re-adding the class definition
with a package-private constructor via Metadata.xml ensures the generator
keeps it while producing proper auto-generated C# bindings.

Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 20, 2026

@copilot you should fix this via Metadata.xml instead of adding manual bindings via Additions!

Switched to Metadata.xml approach in b9c04f8. The fix uses remove-node + add-node to re-define TvContractCompat.WatchNextPrograms with a package-private constructor and all its fields, which prevents the binding generator from dropping it. The manual Additions/TvContractCompat.WatchNextPrograms.cs file has been removed.

Comment on lines 4 to 21
<!-- Remove and re-add TvContractCompat.WatchNextPrograms with a method so the
binding generator does not drop it as an "empty" class. The Java class only has static
final fields (constants) and a private constructor, which causes the generator to skip it. -->
<remove-node path="/api/package[@name='androidx.tvprovider.media.tv']/class[@name='TvContractCompat.WatchNextPrograms']" />
<add-node path="/api/package[@name='androidx.tvprovider.media.tv']">
<class abstract="false" deprecated="not deprecated" extends="java.lang.Object" extends-generic-aware="java.lang.Object" jni-extends="Ljava/lang/Object;" final="true" name="TvContractCompat.WatchNextPrograms" static="true" visibility="public" jni-signature="Landroidx/tvprovider/media/tv/TvContractCompat$WatchNextPrograms;">
<constructor deprecated="not deprecated" final="false" name="TvContractCompat.WatchNextPrograms" jni-signature="()V" bridge="false" static="false" type="androidx.tvprovider.media.tv.TvContractCompat.WatchNextPrograms" synthetic="false" visibility="" />
<field deprecated="not deprecated" final="true" name="CONTENT_URI" jni-signature="Landroid/net/Uri;" static="true" transient="false" type="android.net.Uri" type-generic-aware="android.net.Uri" visibility="public" volatile="false" />
<field deprecated="not deprecated" final="true" name="CONTENT_TYPE" jni-signature="Ljava/lang/String;" static="true" transient="false" type="java.lang.String" type-generic-aware="java.lang.String" value="&quot;vnd.android.cursor.dir/watch_next_program&quot;" visibility="public" volatile="false" />
<field deprecated="not deprecated" final="true" name="CONTENT_ITEM_TYPE" jni-signature="Ljava/lang/String;" static="true" transient="false" type="java.lang.String" type-generic-aware="java.lang.String" value="&quot;vnd.android.cursor.item/watch_next_program&quot;" visibility="public" volatile="false" />
<field deprecated="not deprecated" final="true" name="WATCH_NEXT_TYPE_CONTINUE" jni-signature="I" static="true" transient="false" type="int" type-generic-aware="int" value="0" visibility="public" volatile="false" />
<field deprecated="not deprecated" final="true" name="WATCH_NEXT_TYPE_NEXT" jni-signature="I" static="true" transient="false" type="int" type-generic-aware="int" value="1" visibility="public" volatile="false" />
<field deprecated="not deprecated" final="true" name="WATCH_NEXT_TYPE_NEW" jni-signature="I" static="true" transient="false" type="int" type-generic-aware="int" value="2" visibility="public" volatile="false" />
<field deprecated="not deprecated" final="true" name="WATCH_NEXT_TYPE_WATCHLIST" jni-signature="I" static="true" transient="false" type="int" type-generic-aware="int" value="3" visibility="public" volatile="false" />
<field deprecated="not deprecated" final="true" name="COLUMN_WATCH_NEXT_TYPE" jni-signature="Ljava/lang/String;" static="true" transient="false" type="java.lang.String" type-generic-aware="java.lang.String" value="&quot;watch_next_type&quot;" visibility="public" volatile="false" />
<field deprecated="not deprecated" final="true" name="COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS" jni-signature="Ljava/lang/String;" static="true" transient="false" type="java.lang.String" type-generic-aware="java.lang.String" value="&quot;last_engagement_time_utc_millis&quot;" visibility="public" volatile="false" />
</class>
</add-node>
Copy link
Member

Choose a reason for hiding this comment

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

@copilot instead of removing and re-adding, can you just update visibility on the members you need the visibility changed? You should not need to remove/re-add, just update the values in-place, so it's more clear what you are doing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the remove-node in 9818920 — it was unnecessary since the class is already absent from api.xml (the binding generator drops it before Metadata.xml transforms run). Now it's just a single add-node.

Unfortunately, an in-place visibility update isn't possible here because the entire class gets dropped from api.xml during the class-parseapi.xml conversion (classes with only static final fields and no public constructors/methods are treated as empty). So we do need the full add-node with the class definition, constructor, and fields.

The class is already absent from api.xml (dropped by the binding generator
before Metadata.xml transforms run), so remove-node was unnecessary.
Now uses a single add-node to add the class with a package-private
constructor and all fields.

Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com>
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.

[Xamarin.AndroidX.TvProvider] TvContractCompat.WatchNextPrograms class is missing

2 participants