Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create process to automatically generate AndroidManifest.xml attributes #8272

Closed
jpobst opened this issue Aug 14, 2023 · 0 comments · Fixed by #8781
Closed

Create process to automatically generate AndroidManifest.xml attributes #8272

jpobst opened this issue Aug 14, 2023 · 0 comments · Fixed by #8781
Assignees
Labels
Area: Mono.Android Issues with the Android API binding (Mono.Android.dll). enhancement Proposed change to current functionality.
Milestone

Comments

@jpobst
Copy link
Contributor

jpobst commented Aug 14, 2023

Context: #8235

New API levels often add new AndroidManifest.xml elements that can be specified. We make these available to users as C# attributes, eg: [IntentFilter].

This requires updates to multiple files:
‎src/Mono.Android/Android.App/IntentFilterAttribute.cs
src/Xamarin.Android.Build.Tasks/Mono.Android/IntentFilterAttribute.Partial.cs

We have a script we can manually run to find any new manifest elements:
https://github.com/xamarin/xamarin-android/tree/main/build-tools/manifest-attribute-codegen

However, making the code changes is tedious and potentially error prone. It would be nice if we had a script we could run that would also automatically generate the needed code changes.

Example change:
#8261

Additionally there is some discussion about this process and undocumented attributes here: #1336

Related issue: #8729

@jpobst jpobst added enhancement Proposed change to current functionality. Area: Mono.Android Issues with the Android API binding (Mono.Android.dll). labels Aug 14, 2023
@jpobst jpobst added this to the .NET 9 Planning milestone Aug 14, 2023
@jpobst jpobst self-assigned this Aug 14, 2023
@microsoft-github-policy-service microsoft-github-policy-service bot added the needs-triage Issues that need to be assigned. label Aug 14, 2023
@jpobst jpobst removed the needs-triage Issues that need to be assigned. label Aug 14, 2023
jonpryor pushed a commit that referenced this issue Aug 18, 2023
Fixes: #8235

Context: #8272

Add the following properties to `IntentFilterAttribute` to allow
the various `AndroidManifest.xml` [`<data/>`][0] attributes to
be generated:

  - `IntentFilterAttribute.DataPathSuffix` generates
    [`//intent-filter/data/@pathSuffix`][1].
  - `IntentFilterAttribute.DataPathSuffixes` generates
    [`//intent-filter/data/@pathSuffix`][1].
  - `IntentFilterAttribute.DataPathAdvancedPattern` generates
    [`//intent-filter/data/@pathAdvancedPattern`][1].
  - `IntentFilterAttribute.DataPathAdvancedPatterns` generates
    [`//intent-filter/data/@pathAdvancedPattern`][1].

Note that while we have a script to detect new elements added to
`AndroidManifest.xml`, the code must be written manually.

TODO: Issue #8272 to automate this code generation.

[0]: https://developer.android.com/guide/topics/manifest/data-element
[1]: https://developer.android.com/guide/topics/manifest/data-element#path
jonathanpeppers pushed a commit that referenced this issue Aug 22, 2023
Fixes: #8235

Context: #8272

Add the following properties to `IntentFilterAttribute` to allow
the various `AndroidManifest.xml` [`<data/>`][0] attributes to
be generated:

  - `IntentFilterAttribute.DataPathSuffix` generates
    [`//intent-filter/data/@pathSuffix`][1].
  - `IntentFilterAttribute.DataPathSuffixes` generates
    [`//intent-filter/data/@pathSuffix`][1].
  - `IntentFilterAttribute.DataPathAdvancedPattern` generates
    [`//intent-filter/data/@pathAdvancedPattern`][1].
  - `IntentFilterAttribute.DataPathAdvancedPatterns` generates
    [`//intent-filter/data/@pathAdvancedPattern`][1].

Note that while we have a script to detect new elements added to
`AndroidManifest.xml`, the code must be written manually.

TODO: Issue #8272 to automate this code generation.

[0]: https://developer.android.com/guide/topics/manifest/data-element
[1]: https://developer.android.com/guide/topics/manifest/data-element#path
jonpryor pushed a commit that referenced this issue Oct 11, 2023
)

Fixes: #8409

Context: #8272

The [`//service/@android:foregroundServiceType`][0] attribute can be
generated based on the value of the
`Android.App.ServiceAttribute.ForegroundServiceType` property:

	[Service(ForegroundServiceType=ForegroundService.TypeCamera)]
	partial class MyService : Service {
	}

which will result in an `AndroidManifest.xml` fragment such as:

	<service android:foregroundServiceType="camera" android:name="crc64….MyService" />

However, a number of `ForegroundService` enum values have been added
without corresponding updates to `ServiceAttribute` XML generation.
Consequently, using "recently added" values such as
`ForegroundService.TypeHealth` would result in those values *not*
being added to the generated `//service/@android:foregroundServiceType`.

Update `ManifestDocumentElement.cs` to update
`ToString(ForegroundService)` so that all current `ForegroundService`
enum values are supported.  This will allow:

	[Service(ForegroundServiceType=
	    ForegroundService.TypeCamera |      // previously supported
	    ForegroundService.TypeMicrophone)]  // new hawtness
	partial class MyService : Service {
	}

to properly emit:

	<service android:foregroundServiceType="camera|microphone" android:name="crc64….MyService" />

[0]: https://developer.android.com/guide/topics/manifest/service-element#foregroundservicetype
jonathanpeppers pushed a commit that referenced this issue Oct 13, 2023
)

Fixes: #8409

Context: #8272

The [`//service/@android:foregroundServiceType`][0] attribute can be
generated based on the value of the
`Android.App.ServiceAttribute.ForegroundServiceType` property:

	[Service(ForegroundServiceType=ForegroundService.TypeCamera)]
	partial class MyService : Service {
	}

which will result in an `AndroidManifest.xml` fragment such as:

	<service android:foregroundServiceType="camera" android:name="crc64….MyService" />

However, a number of `ForegroundService` enum values have been added
without corresponding updates to `ServiceAttribute` XML generation.
Consequently, using "recently added" values such as
`ForegroundService.TypeHealth` would result in those values *not*
being added to the generated `//service/@android:foregroundServiceType`.

Update `ManifestDocumentElement.cs` to update
`ToString(ForegroundService)` so that all current `ForegroundService`
enum values are supported.  This will allow:

	[Service(ForegroundServiceType=
	    ForegroundService.TypeCamera |      // previously supported
	    ForegroundService.TypeMicrophone)]  // new hawtness
	partial class MyService : Service {
	}

to properly emit:

	<service android:foregroundServiceType="camera|microphone" android:name="crc64….MyService" />

[0]: https://developer.android.com/guide/topics/manifest/service-element#foregroundservicetype
jonathanpeppers pushed a commit that referenced this issue Oct 17, 2023
)

Fixes: #8409

Context: #8272

The [`//service/@android:foregroundServiceType`][0] attribute can be
generated based on the value of the
`Android.App.ServiceAttribute.ForegroundServiceType` property:

	[Service(ForegroundServiceType=ForegroundService.TypeCamera)]
	partial class MyService : Service {
	}

which will result in an `AndroidManifest.xml` fragment such as:

	<service android:foregroundServiceType="camera" android:name="crc64….MyService" />

However, a number of `ForegroundService` enum values have been added
without corresponding updates to `ServiceAttribute` XML generation.
Consequently, using "recently added" values such as
`ForegroundService.TypeHealth` would result in those values *not*
being added to the generated `//service/@android:foregroundServiceType`.

Update `ManifestDocumentElement.cs` to update
`ToString(ForegroundService)` so that all current `ForegroundService`
enum values are supported.  This will allow:

	[Service(ForegroundServiceType=
	    ForegroundService.TypeCamera |      // previously supported
	    ForegroundService.TypeMicrophone)]  // new hawtness
	partial class MyService : Service {
	}

to properly emit:

	<service android:foregroundServiceType="camera|microphone" android:name="crc64….MyService" />

[0]: https://developer.android.com/guide/topics/manifest/service-element#foregroundservicetype
jonpryor pushed a commit that referenced this issue Jun 7, 2024
…8781)

Fixes: #8272

Context: #8235
Context: #8729
Context: e790874

Previously, we did not have an established process for detecting new
XML elements and attributes allowed in `AndroidManifest.xml` and
surfacing them to users via our manifest attributes like
`[ActivityAttribute]`.  This leads to users having to use manual
workarounds until our attributes can be updated.

Additionally, whenever we do add new properties to these attributes,
it requires manually updating multiple files by hand that must remain
in sync, eg:

  * [src/Mono.Android/Android.App/IntentFilterAttribute.cs](https://github.com/xamarin/xamarin-android/blob/180dd5205ab270bb74bb853754665db9cb5d65f1/src/Mono.Android/Android.App/IntentFilterAttribute.cs#L9)
  * [src/Xamarin.Android.Build.Tasks/Mono.Android/IntentFilterAttribute.Partial.cs](https://github.com/xamarin/xamarin-android/blob/180dd5205ab270bb74bb853754665db9cb5d65f1/src/Xamarin.Android.Build.Tasks/Mono.Android/IntentFilterAttribute.Partial.cs#L14)

The `build-tools/manifest-attribute-codegen` utility (e790874) has
support to parse Android SDK `attrs_manifest.xml` files, which
specifies what elements and attributes are valid within
`AndroidManifest.xml`.

Update `manifest-attribute-codegen` to do what it's name already
implied: generate code!  It now reads a `metadata.xml` file which
controls which custom attributes to emit, where to emit them, and
what members those custom attributes should have (among other things).
This makes it easier to ensure that code shared by `src/Mono.Android`
and `src/Xamarin.Android.Build.Tasks` are consistent, meaking it
easier to correctly add support for new attributes and/or
attribute members.

Generated file semantics and naming conventions: consider the C# type
`Android.App.ActivityAttribute`.

  * `src\Xamarin.Android.NamingCustomAttributes\Android.App\ActivityAttribute.cs`
    contains the C# `partial` class declaration that can be shared
    by both `src\Mono.Android` and `src\Xamarin.Android.Build.Tasks`.
    This file also contains a `#if XABT_MANIFEST_EXTENSIONS` block
    which is only used by `src\Xamarin.Android.Build.Tasks`.

  * `src/Xamarin.Android.Build.Tasks/Mono.Android/ActivityAttribute.Partial.cs`
    contains the C# `partial` class declaration with code specific
    to `Xamarin.Android.Build.Tasks.dll`.

  * `src/Xamarin.Android.NamingCustomAttributes/Android.App/ActivityAttribute.Partial.cs`
    contains the C# `partial` class declaration with code specific
    to `Mono.Android.dll`.

`metadata.xml` contents and the update process is documented in
`build-tools/manifest-attribute-codegen/README.md`.

Also removed the `ANDROID_*` values from `$(DefineConstants)` for
`Xamarin.Android.Build.Tasks.csproj` as we no longer build separate
assemblies for old Android API levels.

Note this commit does not change any existing manifest attributes or
the properties they expose.  It merely generates what we expose today.
We will determine additional properties to expose in a future commit.
@github-actions github-actions bot locked and limited conversation to collaborators Jul 8, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: Mono.Android Issues with the Android API binding (Mono.Android.dll). enhancement Proposed change to current functionality.
Projects
None yet
1 participant