dotnet / dotnet/android

[TrimmableTypeMap] Revisit Android.Graphics.Color marshaling and dead JniValueMarshaler attribute

Open
#11,681 1 comment 0 reactions 0 assignees View on GitHub
Area: Marshal Methods Area: Mono.Android needs-triage trimmable-type-map
Dominant language
C#
Stars
2.1k
Forks
579
Avg merge
1d 20h
Merged PRs (30d)
257

Description

## Context

While removing `GetValueMarshaler*()` support from the trimmable typemap value manager, we noticed that `Android.Graphics.Color` still has:

```csharp
[JniValueMarshaler (typeof (ColorValueMarshaler))]
public struct Color
```

`ColorValueMarshaler` appears to be legacy support for the old expression-based `jnimarshalmethod-gen.exe` pipeline:

- `JniValueMarshalerAttribute` is only inspected by `ReflectionJniValueManager.GetValueMarshalerCore(Type)`.
- `ColorValueMarshaler`'s runtime object-value methods still throw `NotImplementedException`.
- The only implemented parts are `System.Linq.Expressions`-based methods.
- Current marshal-method support has an explicit `MarshalMethodsClassifier` special case mapping `Android.Graphics.Color` to `System.Int32` because JNI sees Color as an `int`.

## Potential trimmable typemap gap

The trimmable typemap scanner/generator has special handling for primitives, arrays, enums, some well-known interfaces/collections, and `[ExportParameter]` stream/XML kinds, but it does not appear to have an equivalent `Android.Graphics.Color` special case.

This may be a gap for generated direct-dispatch wrappers, for example:

```csharp
[Export]
public Android.Graphics.Color Foo (Android.Graphics.Color c) => c;
```

The scanner may synthesize `Ljava/lang/Object;` for `Color` instead of `I`, and the emitter may not generate the needed conversions:

- JNI `int` -> `new Android.Graphics.Color(int)` for parameters/returns into managed code
- `Android.Graphics.Color` -> `int` (via `ToArgb()` or implicit conversion) for managed return values going back to JNI

## Cleanup opportunity

If `ColorValueMarshaler` is truly dead for current production paths, consider removing the `[JniValueMarshaler]` attribute and possibly the `ColorValueMarshaler` type. This may help reduce trim roots and avoid pulling `System.Linq.Expressions` into apps unnecessarily.

There are likely other expression-marshaler remnants to audit later, but this issue is specifically about `Android.Graphics.Color` and the trimmable typemap path.

## Suggested work

1. Add trimmable typemap scanner/generator tests for `[Export]` / direct-dispatch methods with `Android.Graphics.Color` parameters and return values.
2. Decide whether `Android.Graphics.Color` should be treated as a JNI `I` descriptor in `ManagedTypeToJniDescriptor` / constructor-signature fallback where appropriate.
3. Add emitter support for `int` <-> `Android.Graphics.Color` conversions if direct managed dispatch wrappers need it.
4. Investigate whether removing `[JniValueMarshaler(typeof(ColorValueMarshaler))]` and `ColorValueMarshaler` is source/binary compatible enough, or whether it needs to remain as obsolete/dead public API.
5. Measure whether the cleanup reduces `System.Linq.Expressions` retention in trimmed apps.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the trimmable typemap scanner/generator, ManagedTypeToJniDescriptor, MarshalMethodsClassifier, and the direct-dispatch emitter, then inspect existing tests for Export parameter and return handling. Reproduce the Android.Graphics.Color case for parameters and returns, and verify the generated JNI descriptor and int-to-Color conversions. Separately trace ReflectionJniValueManager.GetValueMarshalerCore(Type) and ColorValueMarshaler before assessing compatibility and trim-size impact.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, csharp
Domain
mobile, tooling
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.