Skip to content

Commit 399b941

Browse files
committed
Merge branch 'main' into dev/grendel/fix-satellite-assembly-count
* main: LEGO: Merge pull request 8818 Bump to dotnet/installer@b40c44502d 9.0.100-preview.3.24165.20 (#8817) Bump com.android.tools:r8 from 8.2.47 to 8.3.37 (#8816) [Mono.Android] Prevent NullPointerException in TranslateStackTrace (#8795) Localized file check-in by OneLocBuild Task (#8815) [Xamarin.Android.Build.Tasks] Make all assemblies RID-specific (#8478) Localized file check-in by OneLocBuild Task (#8813) [Xamarin.Android.Build.Tasks] %(AndroidAsset.AssetPack) Support (#8631) [runtime] Remove the last vestiges of desktop builds (#8810) [ci] Don't auto-retry APK test suites. (#8811) [Microsoft.Android.Templates] Update EN l10n template strings (#8808) Bump to xamarin/Java.Interop/main@651de42 (#8809) [Mono.Android] is now "trimming safe" (#8778) [Mono.Android] Fix missing enum issues that cause BG8800 warnings. (#8707) Bump external/Java.Interop from `3436a30` to `5bca8ad` (#8803) Bump to xamarin/monodroid@77124dc1 (#8804) Bump to dotnet/installer@e911f5c82c 9.0.100-preview.3.24161.2 (#8802) Bump to xamarin/Java.Interop/main@3436a30 (#8799) [templates] Remove redundant "template" from display name. (#8773)
2 parents 35c4644 + 9f548d5 commit 399b941

File tree

224 files changed

+7563
-3559
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

224 files changed

+7563
-3559
lines changed

.external

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
xamarin/monodroid:main@e13723e701307f9f6966d4b309c3eba10a741694
1+
xamarin/monodroid:main@77124dc16985a92077e62b0cfeaeb007c4d4fd2a

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
<NuGetApiPackageVersion>5.4.0</NuGetApiPackageVersion>
4949
<LZ4PackageVersion>1.1.11</LZ4PackageVersion>
5050
<MonoOptionsVersion>6.12.0.148</MonoOptionsVersion>
51-
<SystemCollectionsImmutableVersion>6.0.0</SystemCollectionsImmutableVersion>
51+
<SystemCollectionsImmutableVersion>8.0.0</SystemCollectionsImmutableVersion>
5252
<SystemRuntimeCompilerServicesUnsafeVersion>6.0.0</SystemRuntimeCompilerServicesUnsafeVersion>
5353
<ELFSharpVersion>2.13.1</ELFSharpVersion>
5454
<HumanizerVersion>2.14.1</HumanizerVersion>

Directory.Build.targets

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,13 @@
77
<PackageReference Update="Irony" Version="1.1.0" />
88
</ItemGroup>
99

10+
<!-- Automatically add NRT attribute support for netstandard2.0 projects using NRT -->
11+
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' AND ('$(Nullable)' == 'enable' OR '$(Nullable)' == 'annotations') ">
12+
<Compile Include="$(MSBuildThisFileDirectory)external\Java.Interop\src\utils\NullableAttributes.cs" Visible="false" />
13+
</ItemGroup>
14+
15+
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' AND ('$(Nullable)' == 'enable' OR '$(Nullable)' == 'annotations') ">
16+
<DefineConstants>$(DefineConstants);INTERNAL_NULLABLE_ATTRIBUTES</DefineConstants>
17+
</PropertyGroup>
18+
1019
</Project>
Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
# Android Asset Packs
2+
3+
Google Android began supporting splitting up the app package into multiple
4+
packs with the introduction of the `aab` package format. This format allows
5+
the developer to split the app up into multiple `packs`. Each `pack` can be
6+
downloaded to the device either at install time or on demand. This allows
7+
application developers to save space and install time by only installing
8+
the required parts of the app initially, then installing other `packs`
9+
as required.
10+
11+
There are two types of `pack`: Feature packs and Asset packs.
12+
*Feature* pack contains *non-native* Java code and other resources.
13+
Code in these types of `pack` can be launched via the `Context.StartActivity()`
14+
API call. At this time due to various constraints .NET Android cannot support
15+
Feature packs.
16+
17+
*Asset* packs contain *only*
18+
[`@(AndroidAsset)`](~/android/deploy-test/building-apps/build-items.md#androidasset) items.
19+
It *cannot* contain any code or other resources. This type of `pack` can be
20+
installed at install-time, fast-follow or ondemand. It is most useful for apps
21+
which contain a lot of Assets, such as Games or Multi Media applications.
22+
See the [Android Asset Delivery documentation](https://developer.android.com/guide/playcore/asset-delivery)
23+
for details on how this all works.
24+
25+
## Asset Pack Specification
26+
27+
We want to provide our users the ability to use `Asset` packs without relying
28+
on [Alternative Methods](#alternativemethods)
29+
30+
Add support for new `%(AndroidAsset.AssetPack)` item metadata, which
31+
allows the build system to split up the assets into packs automatically:
32+
33+
```xml
34+
<ItemGroup>
35+
<AndroidAsset Include="Asset/data.xml" />
36+
<AndroidAsset Include="Asset/movie.mp4" AssetPack="assets1" />
37+
<AndroidAsset Include="Asset/movie2.mp4" AssetPack="assets1" />
38+
</ItemGroup>
39+
```
40+
41+
The default value for `%(AndroidAsset.AssetPack)` is `base`, which will
42+
cause the asset to be included in the main application package.
43+
44+
As auto import of items is now common, we need a way for a user to add
45+
this additional attribute to auto included items. This can be done by
46+
using `Update`:
47+
48+
```xml
49+
<ItemGroup>
50+
<AndroidAsset Update="Asset/movie.mp4" AssetPack="assets1" />
51+
<AndroidAsset Update="Asset/movie2.mp4" AssetPack="assets1" />
52+
<AndroidAsset Update="Asset/movie3.mp4" AssetPack="assets2" />
53+
</ItemGroup>
54+
```
55+
56+
`%(AndroidAsset.DeliveryType)` item metadata can be specified to control what
57+
*type* of asset pack is produced. Valid values are:
58+
59+
* `InstallTime`: Asset pack will be delivered when the app is installed.
60+
This is the default value for assets not in the base package.
61+
* `FastFollow`: Asset pack will be downloaded automatically as soon as the app is installed.
62+
* `OnDemand`: Asset pack will be downloaded while the app is running.
63+
64+
The `DeliveryType` for a given asset pack is based on the *first*
65+
`@(AndroidAsset.DeliveryType)` value encountered for a `%(AssetPack)` name.
66+
67+
Consider the following example, in which `Asset/movie2.mp4` and `Asset/movie3.mp4`
68+
are both in the `assets1` pack, which will have a `%(DeliveryType)` of `InstallTime`
69+
(the first encountered value "wins"). `Asset/movie1.mp4` will be in the base package,
70+
while `Asset/movie4.mp4` will be in the "asset2" asset pack.
71+
72+
```xml
73+
<ItemGroup>
74+
<AndroidAsset Update="Asset/movie1.mp4" />
75+
<AndroidAsset Update="Asset/movie2.mp4" AssetPack="assets1" DeliveryType="InstallTime" />
76+
<AndroidAsset Update="Asset/movie3.mp4" AssetPack="assets1" DeliveryType="FastFollow" />
77+
<AndroidAsset Update="Asset/movie4.mp4" AssetPack="assets2" />
78+
</ItemGroup>
79+
```
80+
81+
See Google's [documentation](https://developer.android.com/guide/playcore/asset-delivery#asset-updates) for details on what each of the `DeliveryType` values do.
82+
83+
If however you have a large number of assets it might be cleaner in the
84+
`.csproj` to make use of the `base` value for the `%(AssetPack)` attribute.
85+
In this scenario you update *all* assets to be in a single asset pack then use
86+
`AssetPack="base"` metadata to declare which specific assets end up in the base
87+
aab file. With this you can use wildcards to move most assets into the asset pack:
88+
89+
```xml
90+
<ItemGroup>
91+
<AndroidAsset Update="Assets/*" AssetPack="assets1" />
92+
<AndroidAsset Update="Assets/movie.mp4" AssetPack="base" />
93+
<AndroidAsset Update="Assets/some.png" AssetPack="base" />
94+
</ItemGroup>
95+
```
96+
97+
In this example, `movie.mp4` and `some.png` will end up in the `base` aab file,
98+
but *all the other assets* will end up in the `assets1` asset pack.
99+
100+
At this time the `@(AndroidAsset)` build action does not support `%(AssetPack)`
101+
or `%(DeliveryType)` Metadata in Library Projects.
102+
103+
NOTE: `AssetPacks` are only used when the
104+
[`$(AndroidPackageFormat)`](~/android/deploy-test/building-apps/build-properties.md#debugsymbols)
105+
property is set to `aab` (the default for Release).
106+
When using the `apk` setting the assets will be placed inside the `apk`.
107+
108+
## Release Configuration
109+
110+
In order for the application to function correctly we need to inform the `R8`
111+
linker which Java classes we need to keep. To do this we need to add the
112+
following lines to a `ProGuard.cfg` file which is in the root of our project folder:
113+
114+
```
115+
-keep com.google.android.play.*
116+
```
117+
118+
Alternatively you can create a file called `ProGuard.cfg` and use the
119+
[@(ProguardConfiguration)](~/android/deploy-test/building-apps/build-items.md#proguardconfiguration)
120+
build action. Adding these lines will ensure that all the required Java components are not linked
121+
away during the Release build.
122+
123+
## Testing and Debugging
124+
125+
In order to test your asset packs in the `Debug` configuration, you will need to
126+
make some changes to your `.csproj`. Firstly we need to change the
127+
`$(AndroidPackageFormat)` to `aab`. It will be `aab` by default for `Release` builds,
128+
but will default to `apk` for `Debug` builds. Setting the `AndroidPackageFormat` to `aab`
129+
will disable fast deployment, so it is advised that you only do this when you need to test
130+
your `AssetPacks`.
131+
132+
To test your asset packs add the following to the first `<PropertyGroup/>` in your `.csproj`.
133+
134+
```xml
135+
<AndroidPackageFormat>aab</AndroidPackageFormat>
136+
<AndroidBundleToolExtraArgs Condition=" '$(Configuration)' == 'Debug' ">--local-testing $(AndroidBundleToolExtraArgs)</AndroidBundleToolExtraArgs>
137+
```
138+
139+
The `--local-testing` argument tells the `bundletool` application to install all the asset packs
140+
in a local cache on the device. `InstallTime` packs will be installed during the app installation process.
141+
142+
`FastFollow` packs behave like `OnDemand` packs. They will not automatically installed when the app
143+
is sideloaded. You will need to request them manually when the game starts.
144+
145+
For more details see [https://developer.android.com/guide/playcore/asset-delivery/test](https://developer.android.com/guide/playcore/asset-delivery/test).
146+
147+
## Implementation Details
148+
149+
There are a few changes we need to make in order to support this feature.
150+
One of the issues we will hit is the build times when dealing with large assets.
151+
Current the assets which are to be included in the `aab` are ***copied***
152+
into the `$(IntermediateOutputPath)assets` directory. This folder is
153+
then passed to `aapt2` for the build process.
154+
155+
The new system adds a new directory `$(IntermediateOutputPath)assetpacks`.
156+
This directory would contain a subdirectory for each `pack` that the
157+
user wants to include.
158+
159+
```dotnetcli
160+
assetpacks/
161+
assets1/
162+
assets/
163+
movie2.mp4
164+
assets2/
165+
assets/
166+
movie3.mp4
167+
```
168+
169+
All the building of the `pack` zip file would take place in these subfolders.
170+
The name of the pack will be based on the main "packagename" with the asset pack
171+
name appended to the end. e.g `com.microsoft.assetpacksample.assets1`.
172+
173+
During the build process we identify all the `AndroidAsset` items which
174+
have an `AssetPack` attribute. These files are then copied to the
175+
new `$(IntermediateOutputPath)assetpacks` directory rather than the
176+
existing `$(IntermediateOutputPath)assets` directory. This allows us to
177+
continue to support the normal `AndroidAsset` behavior while adding the
178+
new system.
179+
180+
Once we have collected and copied all the assets we then use the new
181+
`<GetAssetPacks/>` Task to figure out which asset packs we need to create.
182+
We then call the `<CreateDynamicFeatureManifest/>` task to create a required
183+
`AndroidManifest.xml` file for the asset pack. This file will end
184+
up in the same `$(IntermediateOutputPath)assetpacks` directory.
185+
We call this Task `<CreateDynamicFeatureManifest/>` because it can be used
186+
to create any feature pack if and when we get to implement full feature
187+
packs.
188+
189+
```dotnetcli
190+
assetpacks/
191+
assets1/
192+
AndroidManifest.xml
193+
assets/
194+
movie2.mp4
195+
assets2/
196+
AndroidManifest.xml
197+
assets/
198+
movie3.mp4
199+
```
200+
201+
We can then call `aapt2` to build these packs into `.zip` files. A new
202+
task `<Aapt2LinkAssetPack/>` task takes care of this. This is a special version
203+
of `Aapt2Link` which implements linking for asset packs only.
204+
It also takes care of a few problems which `aapt2` introduces. For some
205+
reason the zip file that is created has the `AndroidManifest.xml` file
206+
in the wrong place. It creates it in the root of the zip file, but the
207+
`bundletool` expects it to be in a `manifest` directory.
208+
`bundletool` will error out if its not in the right place.
209+
So `<Aapt2LinkAssetPack/>` takes care of this for us. It also removes a
210+
`resources.pb` which gets added. Again, `bundletool` will error if this
211+
file is in the zip file.
212+
213+
Once the zip files have been created they are then added to the
214+
`@(AndroidAppBundleModules)` ItemGroup. This will ensure that when the
215+
final `.aab` file is generated they are included as asset packs.
216+
217+
## Alternative Methods
218+
219+
An alternative method is available on [github](https://github.com/infinitespace-studios/MauiAndroidAssetPackExample).
220+
This method allows developers to place additional assets in a special
221+
[NoTargets](https://github.com/microsoft/MSBuildSdks/blob/main/src/NoTargets/README.md) project.
222+
This project is built just after the final `aab` is produced. It builds a zip
223+
file which is then added to the `@(Modules)` ItemGroup in the main application.
224+
This zip is then included into the
225+
final app as an additional feature.
226+
227+
Using a separate project like in the hack is one way to go. It does have some
228+
issues though.
229+
230+
1. It is a `special` type of project. It requires a `global.json` which imports
231+
the `NoTargets` sdk.
232+
2. There is no IDE support for building this type of project.
233+
234+
Having the user go through a number of hoops to implement this for
235+
.NET Android or .NET MAUI is not ideal.

Documentation/guides/building-apps/build-items.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,37 @@ or library project is built.
1919
Supports [Android Assets](https://developer.android.com/guide/topics/resources/providing-resources#OriginalFiles),
2020
files that would be included in the `assets` folder in a Java Android project.
2121

22+
Starting with .NET 9 the `@(AndroidAsset)` build action also supports additional metadata for generating [Asset Packs](https://developer.android.com/guide/playcore/asset-delivery). The `%(AndroidAsset.AssetPack)` metadata can be used to automatically generate an asset pack of that name. This feature is only supported when the [`$(AndroidPackageFormat)`](#androidpackageformat) is set to `.aab`. The following example will place `movie2.mp4` and `movie3.mp4` in separate asset packs.
23+
24+
```xml
25+
<ItemGroup>
26+
<AndroidAsset Update="Asset/movie.mp4" />
27+
<AndroidAsset Update="Asset/movie2.mp4" AssetPack="assets1" />
28+
<AndroidAsset Update="Asset/movie3.mp4" AssetPack="assets2" />
29+
</ItemGroup>
30+
```
31+
32+
This feature can be used to include large files in your application which would normally exceed the max
33+
package size limits of Google Play.
34+
35+
If you have a large number of assets it might be more efficient to make use of the `base` asset pack.
36+
In this scenario you update ALL assets to be in a single asset pack then use the `AssetPack="base"` metadata
37+
to declare which specific assets end up in the base aab file. With this you can use wildcards to move most
38+
assets into the asset pack.
39+
40+
```xml
41+
<ItemGroup>
42+
<AndroidAsset Update="Assets/*" AssetPack="assets1" />
43+
<AndroidAsset Update="Assets/movie.mp4" AssetPack="base" />
44+
<AndroidAsset Update="Assets/some.png" AssetPack="base" />
45+
</ItemGroup>
46+
```
47+
48+
In this example, `movie.mp4` and `some.png` will end up in the `base` aab file, while all the other assets
49+
will end up in the `assets1` asset pack.
50+
51+
The additional metadata is only supported on .NET Android 9 and above.
52+
2253
## AndroidAarLibrary
2354

2455
The Build action of `AndroidAarLibrary` should be used to directly

Documentation/guides/building-apps/build-process.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ Extension points include:
195195
196196
- [`$(AfterGenerateAndroidManifest)](~/android/deploy-test/building-apps/build-properties.md#aftergenerateandroidmanifest)
197197
- [`$(BeforeGenerateAndroidManifest)](~/android/deploy-test/building-apps/build-properties.md#beforegenerateandroidmanifest)
198+
- [`$(BeforeBuildAndroidAssetPacks)`](~/android/deploy-test/building-apps/build-properties.md#beforebuildandroidassetpacks)
198199
199200
A word of caution about extending the build process: If not
200201
written correctly, build extensions can affect your build

Documentation/guides/building-apps/build-properties.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,18 @@ APK root directory. The format of the path is `lib\ARCH\wrap.sh` where
832832
+ `x86_64`
833833
+ `x86`
834834

835+
## AndroidIncludeAssetPacksInPackage
836+
837+
This property controls if an Asset Packs build automatically are auto
838+
included in the final `.aab` file. It will default to `true`.
839+
840+
In certain cases the user might want to release an interim release. In
841+
these cases the user does not need to update the asset pack. Especially
842+
if the contents of the asset pack have not changed. This property allows
843+
the user to skip the asset packs if they are not required.
844+
845+
Added in .NET 9
846+
835847
## AndroidInstallJavaDependencies
836848

837849
The default value is `true` for command line builds. When set to `true`, enables
@@ -1674,6 +1686,13 @@ as support for `$(AotAssemblies)` will be removed in a future release.
16741686

16751687
Extra options to pass to `aprofutil`.
16761688

1689+
## BeforeBuildAndroidAssetPacks
1690+
1691+
MSBuild Targets listed in this
1692+
property will run directly before the `AssetPack` items are built.
1693+
1694+
Added in .NET 9
1695+
16771696
## BeforeGenerateAndroidManifest
16781697

16791698
MSBuild Targets listed in this

Documentation/guides/messages/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ package from all the users on device and try again. If that does not work you ca
100100
Fast Deployment is not currently supported on this device.
101101
Please file an issue with the exact error message using the 'Help->Send Feedback->Report a Problem' menu item in Visual Studio
102102
or 'Help->Report a Problem' in Visual Studio for Mac.
103+
+ [XA0138](xa0138.md): %(AndroidAsset.AssetPack) and %(AndroidAsset.AssetPack) item metadata are only supported when `$(AndroidApplication)` is `true`.
104+
+ [XA0139](xa0139.md): `@(AndroidAsset)` `{0}` has invalid `DeliveryType` metadata of `{1}`. Supported values are `installtime`, `ondemand` or `fastfollow`
105+
+ [XA0140](xa0140.md):
103106

104107
## XA1xxx: Project related
105108

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
title: Xamarin.Android error XA0138
2+
description: XA0138 error code
3+
ms.date: 02/05/2024
4+
---
5+
# Xamarin.Android error XA0138
6+
7+
## Issue
8+
9+
%(AndroidAsset.AssetPack) and %(AndroidAsset.AssetPack) item metadata are only supported when `$(AndroidApplication)` is `true`.
10+
11+
## Solution
12+
13+
Remove the 'AssetPack' or 'DeliveryType' Metadata from your `AndroidAsset` build Items in the project the error was raised for.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
title: Xamarin.Android error XA0138
2+
description: XA0138 error code
3+
ms.date: 02/05/2024
4+
---
5+
# Xamarin.Android error XA0138
6+
7+
## Issue
8+
9+
`@(AndroidAsset)` `{0}` has an invalid `DeliveryType` metadata of `{1}`. Supported values are `installtime`, `ondemand` or `fastfollow`.
10+
11+
## Solution
12+
13+
Make sure that all `DeliveryType` attributes are one of the following valid values, `installtime`, `ondemand` or `fastfollow`.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
title: Xamarin.Android error XA0138
2+
description: XA0140 error code
3+
ms.date: 02/05/2024
4+
---
5+
# Xamarin.Android error XA0140
6+
7+
## Issue
8+
9+
The AssetPack value defined for `{0}` has invalid characters. `{1}` should only contain A-z, a-z, 0-9 or an underscore.
10+
11+
## Solution
12+
13+
Make sure that all `AssetPack` attributes only contain valid characters.

0 commit comments

Comments
 (0)