Fixes: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/592736
Fixes: #1498
Context: 0780e27
Context: #1439
What does it take to *use* a new (and unstable!) API level?
Commit 8942eca tried to lay some of this out, but *in principal* the
current process should be:
1. Bind the new API level.
2. Add a new `@(AndroidApiInfo)` entry for the new API level.
3. Specify the `$(TargetFrameworkVersion)` of the new API level when
building a project.
Commit 8ce2537 bound API-P as v8.1.99, finishing steps (1) and (2).
Therefore, step (3) should just work, right?
$ cd samples/HelloWorld
$ ../../bin/Debug/bin/xabuild /p:TargetFrameworkVersion=v8.1.99
# no errors
Success!
Except, when reading the diagnostic log file, we see:
ResolveSdksTask Outputs:
AndroidApiLevel: 27
AndroidApiLevelName: 27
...
TargetFrameworkVersion: v8.1.99
We're using the correct v8.1.99 *binding assembly*, but we're *not*
using the API-P `android.jar`, because the `<ResolveSdks>` task is
treating v8.1.99 (API-P/API-28) as API-27.
Oops.
---
There are three msbuild invocations of consequence here:
1. `xabuild /p:AndroidUseLatestPlatformSdk=True`
2. `xabuild /p:AndroidUseLatestPlatformSdk=True /p:TargetFrameworkVersion=v8.1.99`
3. `xabuild /p:AndroidUseLatestPlatformSdk=False /p:TargetFrameworkVersion=v8.1.99`
(1) is the "default build" scenario (at least so long as our default
project templates specify `$(AndroidUseLatestPlatformSdk)`=True).
This should build the project against the latest *stable* API level
and `$(TargetFrameworkVersion)`, as per 0780e27. This works. (Yay!)
If you want to build an *unstable* API level, then the
`$(TargetFrameworkVersion)` value must be set explicitly, either on
the command-line (as shown here) or by editing the `.csproj`.
(2) and (3) are variations to build using the unstable API-P binding;
they *should* be identical, but due to code-path differences in
`<ResolveSdks>`, they are not necessarily the same.
Both (2) and (3) *should* work; they don't, with different behaviors.
(2) *builds*, but uses the wrong `android.jar` during compilation, as
described above with the `samples/HelloWorld` example.
Fix (2) by setting `ResolveSdks.AndroidApiLevel` to
`ResolveSdks.SupportedApiLevel`, so that it overrides the default
behavior of using the latest *stable* API level value when
`$(AndroidUseLatestPlatformSdk)`=True.
(3) does *not* build:
ResolveSdksTask Outputs:
AndroidApiLevel: P
AndroidApiLevelName: P
...
Task "GetAndroidDefineConstants"
…\Xamarin\Android\Xamarin.Android.Common.targets(910,29):
error MSB4030: "P" is an invalid value for the "AndroidApiLevel" parameter of the "GetAndroidDefineConstants" task. The "AndroidApiLevel" parameter is of type "System.Int32".
Done executing task "GetAndroidDefineConstants" -- FAILED.
(3) doesn't build because the `<GetAndroidDefineConstants/>` task
invocation is provided `$(_SupportedApiLevel)`, which is the above
`AndroidApiLevel` output, and thus contains a value of `P`.
Fix (3) by using `AndroidVersions.GetApiLevelFromId()` to lookup the
correct API level based on the id derived from
`$(TargetFrameworkVersion)` value.
This in turn raises a *different* bug: `aapt package` doesn't like
to use id values, it wants *just* numbers. Fixing *just*
`<ResolveSdks>` results in a build error:
Aapt Task
...
Executing package -f -m -M obj/Debug/android/manifest/AndroidManifest.xml -J /var/folders/1y/wwmg3hv5685ft661f5q2w2100000gn/T/7464w5of.vfk --custom-package com.xamarin.android.helloworld -F obj/Debug/android/bin/packaged_resources.bk -S obj/Debug/res/ -I …/android-toolchain/sdk/platforms/android-P/android.jar --auto-add-overlay --max-res-version P
aapt: error APT0000: max res 0, skipping mipmap-hdpi "max res 0, skipping mipmap-hdpi".
aapt: error APT0000: max res 0, skipping mipmap-mdpi "max res 0, skipping mipmap-mdpi".
aapt: error APT0000: max res 0, skipping mipmap-xhdpi "max res 0, skipping mipmap-xhdpi".
aapt: error APT0000: max res 0, skipping mipmap-xxhdpi "max res 0, skipping mipmap-xxhdpi".
aapt: error APT0000: max res 0, skipping mipmap-xxxhdpi "max res 0, skipping mipmap-xxxhdpi".
obj/Debug/android/manifest/AndroidManifest.xml(7): error APT0000: No resource found that matches the given name (at 'icon' with value '@mipmap/icon').
obj/Debug/android/manifest/AndroidManifest.xml(8): error APT0000: No resource found that matches the given name (at 'icon' with value '@mipmap/icon').
Fix this by updating the `<GetJavaPlatformJar/>` task so that
`GetJavaPlatformJar.TargetSdkVersion` contains an integer API level
value, not the API id. This fixes the `<Aapt/>` error.