The [semantics of the `$(AdbTarget)` property][adb-target] are the
same as the [`adb` Target Device option][adb], which permits any of:
[adb-target]: Documentation/build_process.md
[adb]: https://developer.android.com/studio/command-line/adb.html#issuingcommands
* `-d`: Only attached *device*.
* `-e`: Only attached *emulator*
* `-s SERIAL_NUMBER`: A specifically named target; needed if there
is more than one attached device or emulator.
The problem with commit c4e81655 is that it overrode the
`$(InstallDependsOnTargets)` property to call the `_GrantPermissions`
target, which doesn't properly use `$(AdbTarget)`; it instead
*requires* using the `-s` option, which is inconsistent:
adb -s $(AdbTarget) shell pm grant ...
Remove `-s` from the `adb` invocation so that `$(AdbTarget)` can
contain e.g. `-d` or `-e`, as is intended & documented.
We have a VSTS+macOS build machine which has JDK 9 as the default JDK,
thus causing *all* xamarin-android builds to fail, as `gradlew` and
JDK 9 don't *directly* mix:
Executing: ./gradlew assembleDebug --stacktrace
...
org.gradle.api.ProjectConfigurationException: A problem occurred configuring project ':library'.
...
Caused by: org.gradle.internal.event.ListenerNotificationException:
Failed to notify project evaluation listener.
...
Caused by: java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema
...
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.XmlSchema
When using JDK 9, `gradlew` fails because *something* within it
attempts to use the deprecated type
`javax.xml.bind.annotation.XmlSchema`, and JDK 9 doesn't provide
deprecated modules in the default `$CLASSPATH`.
Knowing that the VSTS machine *also* has JDK 8 installed, we've tried
to "filter out" JDK 9 so that it wouldn't be used; see e.g. a3c43584.
Unfortunately that doesn't work, because on macOS the default JDK used
is [always the JDK with the highest version number][macOS-jdk], and
this can't be easily changed system-wide because changing this
behavior requires "removing" a `Info.plist` file to prevent the JDK
from being "seen" by `/usr/bin/java`:
[macOS-jdk]: https://stackoverflow.com/a/44169445
# Don't use JDK 9 by default on macOS:
$ cd /Library/Java/JavaVirtualMachines/jdk-9.0.4.jdk/Contents
$ mv Info.plist Info.plist.disabled
(Renaming `Info.plist.disabled` to `Info.plist` will restore JDK 9 as
the default JDK on the machine.)
A "proper" fix would presumably involve using and exporting
`$JAVA_HOME` *everywhere*, which isn't currently the case.
[This is something that *should* be explored.][xa-1213]
[xa-1213]: https://github.com/xamarin/xamarin-android/issues/1213
In the meantime, a question: *Can* we build with JDK 9?
*Is it even possible in the first place*?
Turns out, *yes*, it *is* possible. The above `gradlew` error can be
fixed by providing the (new-in-JDK9) `--add-modules` option, so that
the `java.xml.bind` module is accessible:
$ ANDROID_HOME=... JAVA_OPTS="--add-modules java.xml.bind" ./gradlew assembleDebug --stacktrace --no-daemon
# ...works!
Unfortunately, *other* parts xamarin-android get in the way, e.g. the
`<ResolveSdks/>` task doesn't correctly parse the version number out
of `java -version`, and JDK 9 `javac` requires `-source` and `-target`
when `-bootclasspath` is used.
Update the build system and tests so that things *can* be built under
JDK 9.
Additionally, cleanup the internal build system a bit: instead of
having `javac` and `jar` calls strewn throughout *7* different
projects -- all of which would need to be updated to provide usable
`javac -source` and `javac -target` values (JDK 9 doesn't support
`-target 1.6` anymore!), introduce `build-tools\scripts\Jar.targets`
and the new `BuildTestJarFile` target. This takes all
`@(TestJarEntry)` files, compiles them with `javac`, and `jar`s the
compiled files into `%(TestJarEntry.OutputFile)`.
**Note**: This does ***NOT*** mean that building and/or using JDK 9
will be commercially supported in *any* way. (It might not even work!)
When adding a new subfolder in the IDE (VSForMac) we end up with a
folder which has a build action of `@(AndroidAsset)`. This causes the
copy task to fail with:
Cannot copy <folder> to <destfolder>, as the source file doesn't exist",
This is because we assume that all items in `@(AndroidAsset)` (and
`@(AndroidResource)`) are files. It looks like this is not the case.
While a work around is easy -- simply remove the item -- it requires
that the user manually update the `.csproj`.
Instead, use `Directory.Exists()` to check to see if the item is a
directory and skip the item if it is. Otherwise its a file so we
should copy.
We do this in `Files.cs` but also in `AndroidUpdateResDir.cs`. The
latter has been changed to output a list of the "Resolved" files
which will not include any folders.
This is a rewrite of our (very old) NUnit test runner to support tests using
other test suites. The reason for this is that Mono BCL tests are starting to
use xUnit tests and we want to be able to run all of them.
At the same time this code drops support for the "GUI" we previously had to run
tests (not maintained, makes the actual runner code messy) and restructures the
runner infrastructure so that it's possible to add any number of runners in the
future without rewriting any base code. We now use only Android instrumentations
to execute the code.
A few changes to the test running code were necessary since we now support more
than one instrumentation per apk, with different result outputs, options etc.
Support for granting Android permissions on apk install time was added as
well (might be necessary when running tests on devices with Oreo)
Context: https://github.com/xamarin/xamarin-android/pull/1075
PR #1075 keeps rebuilding all the Mono runtimes because of the
`build-tools/mono-runtimes/*` changes -- which invalidate the bundle
hash (97f08f78) -- which means the entire world needs to be rebuilt,
which is *very slow* (7+ hours per build).
This is getting quite tiresome.
Split out the `build-tools/mono-runtimes` changes from PR #1075
so that a new bundle can be built *and cached*, which will speed
up subsequent PR #1075 builds.
Previous commit dd42c9a4 tried to fix apk sizes input filename,
as it was broken for some time. I overlooked that
`%(TestApk.Package)` is part of the item group though and not a
property group as I thought. Thus we got all measurement mixed,
so the last one won and thus we have wrong numbers for the
Mono.Android test. This patch fixes that.
The VSTS build environment was updated to install Java 9.0.1.
[This promptly broke everything][vsts-build] when building
`tests/CodeGen-Binding/Xamarin.Android.LibraryProjectZip-LibBinding`:
[vsts-build]: https://devdiv.visualstudio.com/DevDiv/_build/index?buildId=1224076
Executing: ./gradlew assembleDebug --stacktrace
...
* What went wrong:
Could not determine java version from '9.0.1'.
* Try:
Run with --info or --debug option to get more log output.
* Exception is:
java.lang.IllegalArgumentException: Could not determine java version from '9.0.1'.
at org.gradle.api.JavaVersion.toVersion(JavaVersion.java:70)
at org.gradle.api.JavaVersion.current(JavaVersion.java:80)
The fix is to upgrade to Gradle 4.3 or later, which supports Java 9.
To upgrade the Gradle used, run:
./gradlew wrapper --gradle-version=4.4 --distribution-type=bin --stacktrace
This commit fixes one of the subtle pitfalls of the null conditional
operator (and the biggest issue with it, IMO, as it introduces subtle
*runtime* bugs which may be hard to find, depending on where and how
the code is used)
It is tempting to use the null conditional operator as follows:
string[] arr = null;
if (arr?.Length == 0)
Console.WriteLine ("Array has no elements or is null");
Console.WriteLine ($"Array contains {arr.Length} elements");
However, the above code will throw a `NullReferenceException` in the last
line. The reason is that the conditional expression preceeding it will
yield `false` because the `?.` operator returns a nullable type which, in
this case, will have a value of `null` - and that value is not equal to
`0` obviously. Yet since the conditional expression type is `int?` and
an implicit conversion to `int` exists, the compiler will NOT issue an
error (if you replace `0` with, say, `true` there will be a compilation
error) and happily generate code which will yield a false positive thus
leading to the runtime exception.
While it would be possible to modify the existing condition to the
following form:
if (!(arr?.Length >= 0))
it looks cumbersome and unnecessarily complicates reading the code. Thus,
in instances when the null conditional operator applies to nullable types
instead of reference ones, it is safer to just use the good old long equivalent
to the comfortable ?. shortcut.
Arguably, in this case the NREX won't happen since our array is not `null`,
but I'm a big proponent of correct code, so... :)
This is required for "system" execution on Windows, as there is no
`xbuild-frameworks` folder installed by the Xamarin.Android `.vsix`.
The framework installation location in VS2017 is outlined at:
C:\Program Files (x86)\Microsoft Visual Studio\Preview\Enterprise\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v1.0'
Instead of hardcoding the path to `Xamarin.Android.NUnitLite.dll`,
let MSBuild sort it out by using the the
`<ResolveAssemblyReference/>` task.
One more fix after the migration of running the apk tests to msbuild
(cdf3bcc11a).
The reason of it is that `_AotName` property is not set, when building
the test. This patch moves the property to `Configuration.props` and
renames it to `TestsAotName`, so that it is set in the test project.
I also have to move _RecordApkSizes target to `TestApks.targets` as I
was experiencing troubles with `AfterTargets` dependency. It looks
like `xbuild` didn't run it the second time, even when the target was
called from project called by MSBuild task.
So to overcome this dependency issue, I moved the target to avoid
using `AfterTargets`. This also means that we can now easily measure
the sizes of the other tests as well (on demand).
Context: https://github.com/mono/mono/pull/5984
Moves `tests/Xamarin.Android.Bcl-Tests/Resources/LinkerDescription.xml`
into mono.
Mono now has additional tests and embeds the `LinkerDescription.xml`
directly into the test assemblies, so we can remove it here.
In some QA needs to run tests on devices without a network
connection, so an option to disable tests that rely on the network in
`Mono.Android-Tests` is needed.
NUnit has the option to include or exclude tests based on the
`[CategoryAttribute]` custom attribute. Various tests that appear to
use the internet are now decorated with `[Category("InetAccess")]`.
To verify this works, I ran the tests with my internet disabled. The
test run for `Mono.Android-Tests` went down from 106 to 84 tests,
with no failures.
To exclude a category on Windows, specify `$(ExcludeCategories)`
msbuild Xamarin.Android.sln /t:RunApkTests /p:ExcludeCategories=InetAccess
On MacOS/Linux, set the `EXCLUDECATEGORIES` make variable:
make run-apk-tests EXCLUDECATEGORIES=InetAccess
If you want to specify multiple categories, use `:` (colon) between
each category. This delimiter is used for various values throughout
Xamarin.Android's build because it works well from the command line
for both MSBuild and make.
Categories can also be explicitly included, by setting the
`$(IncludeCategories)` MSBuild property or the `INCLUDECATEGORIES`
make variable.
Other Android projects (such as test APKs), set `$(TargetFrameworkVersion)`
by importing `Configuration.props` and using `$(AndroidFrameworkVersion)`.
`$(AndroidUseLatestPlatformSdk)` should also be set to `false`.
Not sure why this hasn't caused any issues yet, I first noticed this
causing a failure on PR #997.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=60185
Newer versions of NDK don't include API 4 anymore but two of our tests specified
that they required that particular version to build. This caused the tests to
fail because the android-4 platform path was nowhere to be found.
Bump the minimum SDK version to 9 (which is the lowest platform included in the NDK
as of now)
Do not use `%(TestApk.ResultsPath)` as base filename for performance
measurements anymore; it was changed recently by 385699a5. Instead,
pass own results filename to the `<ProcessLogcatTiming/>` and
`<ProcessPlotInput/>` tasks.
Also add a `ProcessLogcatTiming.LabelSuffix` parameter to the task,
so that it is easier to create merged measurements. It comes handy as
more tests are run in multiple configurations now. It also simplifies
the use of definitions files as we don't need one per configuration.
Context: https://bugzilla.xamarin.com/show_bug.cgi?id=22074
Context: https://bugzilla.xamarin.com/show_bug.cgi?id=59293
Context: https://developer.xamarin.com/releases/android/xamarin.android_6/xamarin.android_6.1/#Improved_Java_Interface_Versioning_Support
**Background**:
Until [C# gains support for default interface methods][ifaces], there
is an "impedance mismatch" between Java interfaces and C# interfaces:
Java methods can be added to interfaces *without* requiring that
existing classes implementing those interfaces implement the "new"
methods. (*This is not* Java default interface methods!)
[ifaces]: https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md
Consider [`android.database.Cursor`][cursor]:
[cursor]: https://developer.android.com/reference/android/database/Cursor.html
```java
// API-1
interface Cursor {
void close();
// ...
}
class MyCursor implements Cursor {
public void close() {}
}
```
The `Cursor` interface had several methods added to it over time --
*before* the Android SDK supported default interface methods! --
e.g. the addition of `Cursor.getType()` in API-11:
```java
interface Cursor {
// in API-1
void close();
// ...
// Added in API-11
int getType(int columnIndex);
}
```
Question: What happens when `MyCursor.getType()` is invoked, if/when
`MyCursor` *has not* been recompiled?
```java
Cursor c = new MyCursor(); // Implements API-1 API, *not* API-11!
c.getType(0); // Method added in API-11!
```
What happens is that an [`AbstractMethodError`][ame] is thrown.
[ame]: https://developer.android.com/reference/java/lang/AbstractMethodError.html
Compare to C#, in which *the type cannot be loaded* if an interface
has a method added:
[ERROR] FATAL UNHANDLED EXCEPTION: System.TypeLoadException: VTable setup of type MyCursor failed
What this meant is [Bug #22074][b22074]: if you have a
Xamarin.Android library, and that library:
1. Has `$(TargetFrameworkVersion)`=v2.3 (API-10), and
2. Has a type which implements `Android.Database.ICursor`
and you then use the type (2) in an App which has
`$(TargetFrameworkVersion)`=v4.4, the app would crash with a
`TypeLoadException`.
[b22074]: https://bugzilla.xamarin.com/show_bug.cgi?id=22074
The fix, [introduced in Xamarin.Android 6.1][xa6.1], is the
`FixAbstractMethodsStep` step, which looks at every type in every
assembly to be included in the `.apk`, and checks to see if that type
is "missing" any abstract methods. If any such type is found, then
the "missing" method is *inserted*, and it will throw an
`AbstractMethodError`.
[xa6.1]: https://developer.xamarin.com/releases/android/xamarin.android_6/xamarin.android_6.1/#Improved_Java_Interface_Versioning_Support
For example, if an assembly `Lib.dll` built against API-10 has:
```csharp
public class MyCursor : Java.Lang.Object, Android.Database.ICursor {
// Implement `ICursor` methods from API-10
}
```
then when `Lib.dll` is packaged as part of an API-11+ app the
`FixAbstractMethodsStep` step will *add* the following method:
```csharp
int ICursor.GetType(int columnIndex)
{
throw new Java.Lang.AbstractMethodError();
}
```
**The Problem**: The Xamarin.Forms team ran into an issue with
[the debugger in Visual Studio][b59293]. During investigation it
turned out that our `FixAbstractMethodsStep` injects two methods
which were not needed, as the methods were already implemented.
[b59293]: https://bugzilla.xamarin.com/show_bug.cgi?id=59293
**The Fix**: Improve "missing abstract method" detection by looking
in `MethodDefinition.Overrides` to find the interface method and
compare it to the interface method we are looking for, not just
using the method name. This will be more resilient to compiler
changes -- not all compilers emit the same name for explicitly
implemented interface methods -- and prevent us from emitting
explicit interface methods when they're already present.
Context: 0077d151
Context: d1d9820a
A "funny" thing happened when commit e9daf5ea didn't build on Jenkins:
I realized that not all tests were run in all configurations. From
commit d1d9820a:
> Why are some tests Debug-only and some aren't?
The answer: time, primarily. Why run tests multiple times, when they
can be potentially time-consuming?
While tests can be slow, they're not always *that* slow -- except for
`Xamarin.Android.Build.Tests` and the BCL tests -- and even there,
program behavior can alter between Debug and Release configurations.
See in particular commit 0077d151, in which the BCL tests are run only
in the Debug configuration because tests *failed* when run in the
Release configuration.
The desire, then, is to run *all* tests in both Debug and Release
configurations. Yes, it'll take longer! So what! (Within reason:
`Xamarin.Android.Build.Tests` should only be run once!)
However, this raises two problems:
1. Filename collisions
2. Jenkins unit test display
Until now, all tests wrote files into a filename that didn't include
the Configuration, e.g. `TestResult-Mono.Android_Tests.xml`. If we did
run these tests twice, the second test invocation would overwrite the
first test invocation. This isn't desirable.
Then there's the display on Jenkins: if we did have e.g.
`TestResult-Mono.Android_Tests-Debug.xml` and
`TestResult-Mono.Android_Tests-Release.xml`, how will Jenkins display
that information? I haven't tested, but I would assume that one of two
things will occur, assuming reasonable Jenkins behavior:
1. Each test will be listed twice, e.g.
ApplicationContextIsApp
ApplicationContextIsApp
2. They'll be "merged" into a single entry.
Neither of these behaviors is desirable: if Debug passes but Release
fails, we need to be able to differentiate between them. Neither of
these possible renderings allows us to tell which configuration fails.
Solve both of these problems by introducing a new `<RenameTestCases/>`
task. This task takes three values of importance:
```xml
<RenameTestCases
Configuration="CONFIGURATION"
SourceFile="SOURCE"
DestinationFolder="DESTINATION"
/>
```
The `<RenameTestCases/>` task will read in `SOURCE`, and if `SOURCE`
is an XML file which we determine is NUnit2-formatted XML (root
element of `<test-case/>`), we will update every `//test-case/@name`
value so that it ends with ` / CONFIGURATION`. The updated XML is
then written to the `DESTINATION` directory, with a filename that
contains `CONFIGURATION`, and `SOURCE` is deleted.
Thus, if we have a Debug-configuration
`TestResult-Mono.Android_Tests.xml` file with XML fragment:
```xml
<test-case
name="Mono.Android_Tests, Android.AppTests.ApplicationTest.ApplicationContextIsApp"
...
/>
```
then `<RenameTestCases/>` will create the file
`TestResult-Mono.Android_Tests-Debug.xml` file with XML fragment:
```xml
<test-case
name="Mono.Android_Tests, Android.AppTests.ApplicationTest.ApplicationContextIsApp / Debug"
...
/>
```
This allows us to run tests in both Debug and Release configurations
while not inadvertently overwriting the `TestResults*.xml` files that
Jenkins reads, and ensuring that the Jenkins test result output is
rendered in a meaningfully useful fashion.
Aside: when updating `//test-case/@name`, the resulting value *cannot*
end in `)`. If it does, then the `(root)` package name issue fixed in
commit 23b2642e reappears for the `generator` unit tests.
**Completely random aside about the state of `xbuild`**:
A development version of `<RenameTestCases/>` was "saner", using
`ITaskItem[]` and not string:
```csharp
partial class RenameTestCases {
public ITaskItem[] SourceFiles {get; set;}
// vs.
// public string SourceFile {get; set;}
}
```
The problem is that the above, while entirely reasonable, did not work
at all correctly with `xbuild`:
```xml
<RenameTestCases SourceFiles="%(TestApk.ResultsPath)" />
```
Under `xbuild`, MSBuild properties would not be expanded, e.g.
`RenameTestCases.SourceFiles` would get a "bizarro" value of e.g.
`$(OutputPath)Mono.Android_Tests-Signed.apk`, which is *useless* and
would result in `FileNotFoundException`s.
MSBuild proper, of course, worked as desired.
TODO: Once this is merged, update the Jenkins Configuration page so
that instead of:
make run-all-tests V=1 || exit 1
it instead runs both Debug and Release configuration tests:
make run-all-tests SKIP_NUNIT_TESTS=1 V=1 || exit 1
make run-all-tests CONFIGURATION=Release V=1 || exit 1
Note that `$(SKIP_NUNIT_TESTS)` is specified so that we only run the
lengthy (1+hr!) `Xamarin.Android.Build.Tests` tests in the Release
configuration, not the Debug + Release configurations.
The results reporting acted weird and hid 2 failures, which were not
reported in the instrumentation result lines
INSTRUMENTATION_RESULT: failed=0
INSTRUMENTATION_RESULT: inconclusive=0
INSTRUMENTATION_RESULT: passed=20134
INSTRUMENTATION_RESULT: run=20466
INSTRUMENTATION_RESULT: nunit2-results-path=/data/data/Xamarin.Android.Bcl_Tests/files/.__override__/TestResults.xml
INSTRUMENTATION_RESULT: skipped=322
INSTRUMENTATION_CODE: -1
and were only reported in the
`TestResult-Xamarin.Android.Bcl_Tests-Release.xml` file.
From `adb logcat` output we can see the crash (same for both failures):
--------- beginning of crash
E/AndroidRuntime( 3826): FATAL EXCEPTION: main
E/AndroidRuntime( 3826): Process: Xamarin.Android.Bcl_Tests, PID: 3826
E/AndroidRuntime( 3826): android.runtime.JavaProxyThrowable: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NotSupportedException: Linked away.
E/AndroidRuntime( 3826): at (wrapper managed-to-native) System.Object:__icall_wrapper_ves_icall_object_new_specific (intptr)
E/AndroidRuntime( 3826): at MonoTests.System.Runtime.Remoting.ContextTest..ctor () [0x00000] in <0484cb939a1a4a72be4938b3c08edcaa>:0
E/AndroidRuntime( 3826): at (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke (System.Reflection.MonoCMethod,object,object[],System.Exception&)
E/AndroidRuntime( 3826): at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00002] in <0e1d684ae38a4822aaf6364f06390ad6>:0
E/AndroidRuntime( 3826): --- End of inner exception stack trace ---
That lead us to [`mono/mono/metadata/object.c`][object.c] source,
where `mono_error_set_not_supported (error, "Linked away.");` is
used 6 times.
[object.c]: https://github.com/mono/mono/blob/b263d37/mono/metadata/object.c#L5303
One of the cases was related to:
```c
im = mono_class_get_method_from_name (klass, "CreateProxyForType", 1);
```
That led us to the linked away
`System.Runtime.Remoting.Activation.ActivationServices.CreateProxyForType()`
method.
Update `Xamarin.Android.Bcl-Tests/Resources/LinkerDescription.xml` to
preserve `ActivationServices.CreateProxyForType()`, allowing these
tests to succeed in a `LinkSDKOnly` environment.
Some of the tests use reflection to access BCL API. Parts of the
needed API is linked away by the linker. The link description file
makes sure the needed parts stay in the mscorlib and thus the tests
don't fail.
This fixes remaining issues [^1] in `Xamarin.Android.Bcl-Tests` in
Release configuration and the test should run without failures
when linked (LinkSdkOnly).
[^1]: After merging https://github.com/xamarin/xamarin-android/pull/933
Context: https://devdiv.visualstudio.com/DevDiv/_build/index?buildId=1047263
A couple of fixes to get `Xamarin.Android.Bcl-Tests` and
`Xamarin.Android-Tests.sln` compiling on Windows:
The `<SystemUnzip/>` task is passing some file paths to
`Directory.EnumerateFiles()`:
System.IO.IOException: The directory name is invalid.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileSystemEnumerableIterator`1.CommonInit()
at System.IO.FileSystemEnumerableIterator`1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler`1 resultHandler, Boolean checkHost)
at System.IO.Directory.EnumerateFiles(String path, String searchPattern, SearchOption searchOption)
at Xamarin.Android.BuildTools.PrepTasks.SystemUnzip.<ExtractFile>d__22.MoveNext() in E:\A\_work\1\s\build-tools\xa-prep-tasks\Xamarin.Android.BuildTools.PrepTasks\SystemUnzip.cs:line 128
Fix this by renaming `SystemUnzip.GetExtractedSourceEntries()` to
`SystemUnzip.GetExtractedSourceDirectories()` and have it return
only directories.
MSBuild is getting a duplicate `@(Compile)` entry passed to `<Csc/>`
for `obj/Debug/App.cs`. There was a conditional `@(Compile)` entry as
well as one added during the `_GenerateApp_cs` target. It seems simpler to
just remove the condition and the duplicate `@(Compile)` entry, since
`$(BuildDependsOn)` causes the `_GenerateApp_cs` target to run first.
Commit d1d9820a enabled `Xamarin.Android.Bcl-Tests` to build and run
in the Release configuration. This was the right idea, but the wrong
time: [The Jenkins build for xamarin-android/d0d8640b][xad0] reports
68 failures, due to running the `Xamarin.Android.Bcl-Tests` in the
Release configuration, in which the linker is *enabled*.
[xad0]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/666/
Enabling the linker is breaking these tests. :-(
This needs to be addressed -- enabling the linker should *not* break
the BCL unit tests! -- but in the meantime, partially revert commit
d1d9820a and only run the BCL unit tests in the Debug configuration,
removing this source of unit test failures.
The [Jenkins `xamarin-android` build][xae9] for commit e9daf5ea was
unexpectedly UNSTABLE, because an error was encountered:
[xae9]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/662/
Tool …/adb execution started with arguments: -s emulator-5570 install "…/xamarin-android/tests/../bin/TestRelease/Xamarin.Android.Bcl_Tests-Signed.apk"
adb: error: cannot stat '…/xamarin-android/tests/../bin/TestRelease/Xamarin.Android.Bcl_Tests-Signed.apk':
No such file or directory
The error was encountered because `tests/Xamarin.Android.Bcl-Tests`
wasn't built for the Release configuration, because it wasn't part of
`$(TEST_APK_PROJECTS_RELEASE)` within `Makefile`.
This raises an interesting question: what is the best solution?
1. Make `Xamarin.Android.Bcl-Tests` a Debug-only unit test.
2. Build and run `Xamarin.Android.Bcl-Tests` in both Debug & Release.
...quickly followed by a *second* question:
Why are some tests Debug-only and some aren't?
I don't have a good handle on this second question, other than that it
would "duplicate" unit test execution, thus lengthening build times.
However, I'm not convinced that's a good rationale, either: the
Release runtime has optimizations (`-O0 -fno-omit-frame-pointer` Debug
vs. `-O2` Release), which could theoretically break a great many
things. The Release runtime is also what is used in our commercial
products; the Debug runtime is largely only useful for #runtime
debugging.
We thus should want as many tests as possible to run in Release, not
as few as possible
This allows us to tentatively answer the first question: we should add
`Xamarin.Android.Bcl-Tests` to `$(TEST_APK_PROJECTS_RELEASE)` so that
it's run in *both* Debug *and* Release configurations. This in turn
will ensure that the failing `adb install` command succeeds, which
*should* allow the build to PASS, as desired.
What do we want? (with apologies to 48e3fc26)
**MOAR** Unit tests!
Specifically, we want to run the BCL unit tests which mono generates:
$ cd external/mono/mcs/class/corlib
$ make PROFILE=monodroid test
# creates `monodroid_corlib_test.dll`
Creation of `monodroid_*_test.dll` assemblies and the
`make PROFILE=monodroid test` target is a relatively recent
development, for which I need to buy the #runtime team some beers.
In terms of `mono-runtimes.targets`, we can build *all* of the BCL
unit test assemblies with:
$ cd external/mono/mcs/class
$ make -i do-test PROFILE=monodroid
Now that we can create them, how do we *use* them? That's the trickier
bit: they need to be built within mono, as part of the existing BCL
build process. This in turn means that the BCL unit test assemblies
need to be distributed as part of the mono bundle, as we don't want to
rebuild the mono repo "from scratch" just for the unit tests.
Update `build-tools/mono-runtimes/ProfileAssemblies.projitems` to
include a new `@(MonoTestAssembly)` item group which contains all of
the BCL unit test assemblies and related files which should be
included into `bundle-*.zip`. Additionally, add
`ProfileAssemblies.projitems` to `@(VersionFile)` witihin
`bundle-path.targets`, so that if anything within
`ProfileAssemblies.projitems` changes, we rebuild the bundle.
Once we *have* the BCL unit test assemblies, and their dependencies,
we need to *run* them. The new `Xamarin.Android.Bcl-Tests.csproj`
project is a Xamarin.Android application project which will execute
the unit tests.
There's just one small problem: Xamarin.Android apps want to use
`Xamarin.Android.NUnitLite.dll`. The BCL unit test assemblies instead
build against their own `nunitlite.dll`, which has no Xamarin.Android
integration or support. How do we use the new test assemblies?
*Force* a fix by using `remap-assembly-ref` to "rename" the
`nunitlite` assembly reference to `Xamarin.Android.NUnitLite.dll`.
This *cannot* be done as part of the `mono-runtimes.mdproj` build, as
`Xamarin.Android.NUnitLite.dll` won't yet exist. Instead, remap the
assemblies within `Xamarin.Android.Bcl-Tests.targets`, and distribute
the remapped assemblies with the application.
Finally, address one other "small" problem: not all of the unit tests
pass! Some of these are for reasons we don't know, and others will
require changes to `mono`.
Update `Xamarin.Android.NUnitLite` to allow *filtering* of tests:
namespace Xamarin.Android.NUnitLite {
partial class TestSuiteActivity {
public ITestFilter Filter {get; set;}
public virtual void UpdateFilter ();
}
partial class TestSuiteInstrumentation {
public ITestFilter Filter {get; set;}
public virtual void UpdateFilter ();
}
}
`TestSuiteActivity.UpdateFilter()` is called by
`TestSuiteActivity.OnCreate()`, *after* `GetIncludedCategories()` and
`GetExcludedCategories()` are called, to allow subclasses to alter the
`ITestFilter` which is used to determine which tests are executed.
`TestSuiteInstrumentation.UpdateFilter()` is called by
`TestSuiteInstrumentation.OnStart()`, *after*
`GetIncludedCategories()` and `GetExcludedCategories()` are called, to
allow subclasses to alter the `ITestFilter` which is used to determine
which tests are executed.
`Xamarin.Android.Bcl_Tests` overrides both of these and updates the
`Filter` property so that "known failing" tests are excluded. This
allows us to skip failing tests, giving us time to properly fix them
in time while allowing the rest of this PR to be merged.
The skipped tests include:
* MonoTests.System.Reflection.AssemblyTest.GetReferencedAssemblies
* MonoTests.System.ServiceModel.Description.WebInvokeAttributeTest.RejectTwoParametersWhenNotWrapped
- Needed to `nuget restore Xamarin.Android-Tests.sln`
- Added `$(XAIntegratedTests)` property which defaults to True.
Windows will need to set this property in order to build
`Xamarin.Android-Tests.sln`
- Some project references in `Mono.Android-Tests.csproj` should
be conditional against `$(XAIntegratedTests)`==True
- Usage of `zip -r` is replaced with `jar cf` using `$(JarPath)`
(Windows doesn't have `zip`)
- `Xamarin.Android.Build.Tasks.csproj` had a file-locking issue
similar to `create-vsix.csproj` (2bca09d1): the
`_GenerateXACommonProps` target needs to depend on `ResolveReferences`
Other changes:
- Update README
- Update .gitignore for `.gradle/` and `*.user` files
This reverts commit ae2791a1d7.
The PR was intended just for testing on Jenkins PR builder. Was
labeled `do-not-merge`. I should probably state it in the commit
message as well next time, to be better visible.
Windows machines do not include `java` in their path by default, so it is
a better experience to not require it for the build.
Changes to make this happen:
- `$(JavaCPath)` and `$(JarPath)` are configured in
`Configuration.OperatingSystem.props`
- Usage of `javac` and `jar` across the repo use appropriate
variables now
- `generate-os-info` needs to set `$(JavaCPath)` and `$(JarPath)`
- Created a new `<Ant>` MSBuild task
- A couple places, Windows needs `%JAVA_HOME%` to be set, so we
are doing this via `Environment.SetEnvironmentVariable()` in the
`<AcceptAndroidSdkLicenses/>` and `<Ant/>` tasks.
- `Configuration.OperatingSystem.props` is conditional, so it is
possible to build xa-prep-tasks without it
- `<Which/>` needs to accept files without extensions last for
Windows; `$PATHEXT` should be empty on Unix
Commit 53631f2 tried to fix build/run of our forms test. It added its
proj to the TEST_APK_PROJECTS list. Because forms test is used
conditionaly only in the Release configuration, it needs to be
actually added to the TEST_APK_PROJECTS_RELEASE list instead. Noted
the release list in the RunApkTests.targets file.
Also do not run the forms test in Release/Aot so that we don't have
the times measurements in the .csv ouput file twice
Add `tests/Xamarin.Forms-Performance-Integration` to measure UI app
startup times.
Add a new `<RunUITests/>` task to start an app/activity.
Rename `@(UnitTestApk)` to `@(TestApk)`, as it also handles UI tests.
Update `<ProcessLogcatTiming/>` to be able to process the
`adb logcat` output of started Android Activity processes.
Checks for `Exists ('$(AndroidNdkDirectory)\ndk-build')` will not work
on Windows, since the file is named `ndk-build.cmd`.
To fix this, I created a new `NdkBuildPath` property to be used
throughout the build, which will have the correct value on Windows.
PR builds such as [**macOS+xbuild PR Builder** build 1365][0] are
emitting an error from `mono-api-info`, which isn't surfaced as an
error (hence the builds are still green):
[0]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android-pr-builder/1365/consoleText
[ERROR] FATAL UNHANDLED EXCEPTION: Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: 'Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065'
at Mono.Cecil.BaseAssemblyResolver.Resolve (Mono.Cecil.AssemblyNameReference name, Mono.Cecil.ReaderParameters parameters) [0x0015e] in …/xamarin-android/external/Java.Interop/external/cecil/Mono.Cecil/BaseAssemblyResolver.cs:161
This error is raised when processing
`bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v1.0/Xamarin.Android.NUnitLite.dll`
because [`$(MONO_API_INFO_LIB_DIRS)`][1] contains
`-L .../MonoAndroid/v8.0`, but the PR builds are building v7.1, *not*
v8.0, and thus `Mono.Android.dll` isn't in a directory which is found.
[1]: https://github.com/xamarin/xamarin-android-api-compatibility/blob/49b5789/Makefile#L26-L29
`$(MONO_API_INFO_LIB_DIRS)` is wrong in turn because
`make run-api-compatibility-tests` was overriding
`$(STABLE_FRAMEWORKS)` to include frameworks which the PR build
doesn't build.
Update `make run-api-compatibility-tests` so that
`$(STABLE_FRAMEWORKS)` isn't overridden. This will allow
`xamarin-android-api-compatibility` to probe the frameworks based on
what's present, and construct `$(MONO_API_INFO_LIB_DIRS)` accordingly.
Additionally, xamarin-android master builds such as [build #538][2]
were also failing in an unreported manner:
[2]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/538/consoleText
Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: '…/xamarin-android/bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v8.0/OpenTK-1.0.dll, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
at Mono.Cecil.BaseAssemblyResolver.Resolve (Mono.Cecil.AssemblyNameReference name, Mono.Cecil.ReaderParameters parameters) [0x00164] in <336971fa838f4b15a2a3a9274b113045>:0
at CorCompare.AssemblyCollection.LoadAssembly (System.String assembly) [0x0002a] in <d46deda6cbab4407bacfbd3b1ee45bd0>:0
Cannot load assembly file …/xamarin-android/bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v8.0/OpenTK-1.0.dll
The cause for this is that `OpenTK-1.0.dll` is built into the
`MonoAndroid/$(AndroidLatestFrameworkVersion)` framework directory,
and `Configuration.props` was setting
`$(AndroidLatestFrameworkVersion)` to v7.1 (API-25).
Update `$(AndroidLatestFrameworkVersion)` to v8.0, and
`$(AndroidLatestApiLevel)` to 26.
- besides running in different configurations than default (Debug),
we will also use the startup times measurements in the Jenkins
plots
- also fixes a typo in `RunApkTests.targets`, where supposedly
`Condition` was used in place of `Configuration`
- modifies logcat timing file names, so that it is based on test
results filename instead of just package name. that way we can have
multiple timing results for the same test with various
configurations
We have a failure within
`EnvironmentTests.EnvironmentVariablesFromLibraryProjectsAreMerged`
(commit ea6b9b45): the `@(AndroidEnvironment)` from the library
project is not merged into the App `.apk`:
Expected: null
But was: "Well, hello there!"
(The arguments were in the wrong order. Oops.)
The cause for this is due to `<ResolveLibraryProjectImports/>`
attempts to avoid duplicate work; [from the build log][0]
[0]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/526/consoleText
Task "ResolveLibraryProjectImports"
Assemblies:
.../xamarin-android/bin/TestDebug//LibraryResources.dll
Skipped resource lookup for .../xamarin-android/bin/TestDebug/LibraryResources.dll: extracted files are up to date
ResolvedEnvironmentFiles:
*Because* `LibraryResources.dll` was skipped, the
`@(AndroidEnvironment)` entries from `LibraryResources.dll` were also
skipped! Doh!
Update the `<ResolveLibraryProjectImports/>` task so that when
resource extraction for an assembly is skipped, we remember to add the
already-extracted `@(AndroidEnvironment)` values.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=58303
Background: It is possible for a Java type to have
"aliasing bindings": two or more managed types which claim to bind
the same Java type:
// C#
namespace Android.Runtime {
[Register ("java/util/HashMap", DoNotRegisterAcw=true)]
partial class JavaDictionary {
}
}
namespace Java.Util {
[Register ("java/util/HashMap", DoNotRegisterAcw=true)]
partial class HashMap {
}
}
These can't be realistically forbidden.
Enter a new-to-bind Java type:
// Java
public class Bxc58383 extends java.util.HashMap implements java.util.Map {
}
In order to bind the above `Bxc58383` type, `generator` needs to
determine the appropriate binding type to use for `java.util.HashMap`.
`generator`'s approach to supporting aliasing types is (largely) to
ignore the problem (almost) entirely: There Can Be Only One™ mapping
from a Java type to a managed type, so `generator` needs to pick one.
It does so by using the *last* definition encountered in the assembly.
Consequently, for the above set of C# declarations, when `generator`
needs to find the managed type which binds `java.util.HashMap`,
`Java.Util.HashMap` will be chosen, as it is the last declared type.
Unfortunately, "real life" is a bit more complicated:
`Mono.Android.dll` is made up of *thousands* of files, and the order
of types within an assembly is a compiler implementation detail.
As such...the current `Mono.Android.dll` has `JavaDictionary` defined
*after* `HashMap`:
# output truncated for relevance
$ monodis --typedef bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v7.1/Mono.Android.dll | grep 'Dictionary\|HashMap'
1270: Java.Util.Dictionary (flist=12611, mlist=29569, flags=0x100081, extends=0x20b8)
1287: Java.Util.HashMap (flist=12662, mlist=29806, flags=0x100001, extends=0x1388)
3992: Android.Runtime.JavaDictionary (flist=32135, mlist=85344, flags=0x100001, extends=0x20b8)
Because `JavaDictionary` is defined *after* `HashMap`, and both of
those types have `[Register]` attributes which declare that they bind
the *same* Java type, the result is that the binding of `Bxc58383` is
horrifically broken:
// C#
partial class Bxc58383 : global::Android.Runtime.JavaDictionary, global::Java.Util.IMap {
}
Unfortunately, `JavaDictionary` doesn't itself implement `IMap`, so:
error CS0535: 'Bxc58383' does not implement interface member 'IMap.ContainsKey(Object)'
along with 10 other related errors.
Update the `src/Mono.Android` build process so that `JavaDictionary`
and related types will be defined within `Mono.Android.dll` *before*
all the generated types. This allows `HashMap` to be defined last,
allowing `Bxc58383` to be bound without error:
# output truncated
$ monodis --typedef bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v7.1/Mono.Android.dll | grep 'Dictionary\|HashMap'
3703: Android.Runtime.JavaDictionary (flist=34089, mlist=78134, flags=0x100001, extends=0x4e08)
4170: Java.Util.Dictionary (flist=39685, mlist=91737, flags=0x100081, extends=0x4e08)
4187: Java.Util.HashMap (flist=39736, mlist=91974, flags=0x100001, extends=0x40d8)
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=58673
The `@(AndroidEnvironment)` Build action is *supposed to be* usable on
Library projects. When used within a Library project, the
`@(AndroidEnvironment)` files are embedded into the assembly, and
during the App project build they are extracted and merged into the
`environment` file within the `.apk`.
Unfortunately, this behavior was potentially broken in commit
86888322, as if the Library assembly also contains the
`__AndroidLibraryProjects__.zip` embedded resource (e.g. the Library
project has a `@(AndroidResource)` Build action), the extraction of
the `__AndroidLibraryProjects__.zip` resource will inadvertently
remove the previously extracted `@(AndroidEnvironment)` files.
Oops.
Alter the paths provided to `Files.ExtractAll()` -- which was
directly responsible for deleting the environment files -- so that it
won't delete the environment files.
Update the `tests/locales` on-device unit tests to make use of a
Library-provided `@(AndroidEnvironment)`, and add a unit test which
reads the environment variable and asserts that the environment
variable has the expected value.
Context: https://github.com/xamarin/xamarin-android/pull/253#discussion_r82862993
The *intention* is that Jenkins-produced `oss-xamarin.android*.zip`
artifacts be usable on Windows, so that side-by-side testing can be
performed without replacing the system installation. Usage is in
[UsingJenkinsBuildArtifacts.md](Documentation/UsingJenkinsBuildArtifacts).
This isn't *entirely* the case. It was *apparently* the case at the
time of commit 87ca2737, but things have bitrotten since. For
example, following the 87ca2737 instructions would currently result
in an XA0020 `Could not find monodroid` error, because
`class-parse.exe` wasn't where Windows expects it to be (it was in
`lib/mandroid`, not `lib/xbuild/Xamarin/Android`).
This needs to be fixed.
Additionally, PR #253 mentions that, for filesystem organization, it
would be useful if the macOS/Linux directory structure --
`$prefix/bin`, `$prefix/lib/mandroid`,
`$prefix/lib/xbuild/Xamarin/Android`, `$prefix/lib/xbuild-frameworks`
-- more closely resembled the Windows directory structure of
`$MSBuild` and `$ReferenceAssemblies` (as seen in `.vsix` files).
This would turn macOS/Linux into using `$xa_prefix/xbuild` and
`$xa_prefix/xbuild-frameworks` directories.
`$prefix/bin` would only contain `xabuild`. What is currently in
`$prefix/lib/mandroid` would be merged with
`$xa_prefix/xbuild/Xamarin/Android`.
`$xa_prefix` would `$prefix/lib/xamarin.android`.
This would turn the current macOS structure:
$prefix/bin/xabuild
$prefix/bin/generator
$prefix/bin/cross-arm
$prefix/lib/mandroid/generator.exe
$prefix/lib/xbuild-frameworks/MonoAndroid/v1.0/mscorlib.dll
$prefix/lib/xbuild/Xamarin/Android/Xamarin.Android.Common.targets
Into:
$prefix/bin/xabuild
$prefix/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v1.0/mscorlib.dll
$prefix/lib/xamarin.android/xbuild/Xamarin/Android/generator.exe
$prefix/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets
$prefix/lib/xamarin.android/xbuild/Xamarin/Android/Darwin/cross-arm
Other notes:
* The `bundle-*.zip` filename has been has been changed to include a
*hash* of the contents of various files, in particular
`build-tools\mono-runtimes.*`. This was instigated via a
conversation with @kumpera about making the filename more
"idiot-proof": `mono-runtimes.props` contains *compiler flags*,
and if any of those change, then *logically* the bundle should
differ as well, as the mono runtimes may differ in significant
ways. In theory, the `-vXX` version should be used to track this,
but this is a manual change, easy to overlook. The new `-hHASH`
part of the filename should be more automagic.
The new `<HashFileContents/>` task in `xa-prep-tasks.dll` is
responsible for creating the hash value.
* `Configuration.Java.Interop.Override.props` was moved into
`build-tools/scripts`, because that would cleanup the root
directory a bit.
* OS-specific binaries are now placed into
`$prefix/lib/xamarin.android/xbuild/Xamarin/Android/$(HostOS)`.
On a theoretical plus side, this means that the same build
directory can contain OS-specific binaries for multiple operating
systems. (I don't know if anyone shares a build tree between e.g.
macOS and Linux, but if anyone *does*...)
Unfortunately this requires a workaround for an `xbuild` bug:
`%(_LlvmRuntime.InstallPath)` and
`%(_MonoCrossRuntime.InstallPath)` *cannot* use MSBuild
properties, e.g. `<InstallPath>$(HostOS)/</InstallPath>` doesn't
work as desired; it's instead treated literally.
Special-case `%(InstallPath)` until we fully migrate to MSBuild.
* `$(MonoAndroidToolsDirectory)` should be considered *dead*, along
with `$(MonoAndroidBinDirectory)`, as these should now *always*
be the same directory as where `Xamarin.Android.Build.Tasks.dll`
is located, or a `$(HostOS)` sub-directory.
* `Xamarin.ProjectTools.csproj` needed to be updated to ensure that
the build order was correct.
* Remove all `[Obsolete]` and unreferenced members from
`Xamarin.Android.Build.Utilities.dll`. There's too much in there,
and it makes my head hurt trying to understand the
interrelationships between it all. If it's not used, it's gone.
* The changes to `src/monodroid/jni/Android.mk` are...weird. The
removal of `-I$(topdir)/libmonodroid/zip`/etc. is to reduce use of
non-existent paths, as `$(topdir)` isn't defined, so that's
*actually* `-I/libmonodroid/zip`, which is nonsensical. So far,
so good. What's *odd* is the addition of `$(LOCAL_PATH)` to
`$(LOCAL_C_INCLUDES)`: This is needed so that
`external/mono/support/zlib-helper.c` exports `CreateZStream` and
related symbols, otherwise we get a unit test failure in
`GzipStreamTest.Compression` due to an
`EntryPointNotFoundException`, because `CreateZStream` isn't
exported/public.
What's odd here is that I don't understand what caused this
behavior to change. Previous builds exported `CreateZStream`,
otherwise the tests would fail, and I don't understand how any of
the other changes in this PR would be at fault, though that's
certainly the most plausible explanation.
Regardless, `-Ijni` *first* (due to adding `$(LOCAL_PATH)` to
`$(LOCAL_C_INCLUDES)`) is the desired behavior, so that
`jni/config.h` is included, thus ensuring that `MONO_API` has the
required definition when building `zlib-helper.c`.
This fixes a 'gradlew' failure which is encountered on Windows only. Unfortunately, the 'gradlew' invocation prefixes the 'sdk.dir' value read from 'local.properties' with the path of the working directory.
As a result, we encounter a failure along the following lines on Windows:
```
* What went wrong:
A problem occurred configuring project ':library'.
> The SDK directory 'C:\Users\xamarinqa\git\xamarin-android\tests\CodeGen-Binding\Xamarin.Android.LibraryProjectZip-LibBinding\java\JavaLib\C:Program Files (x86)Androidandroid-sdk' does not exist
```
This can be avoided by exporting ANDROID_HOME in the Exec portion of the BuildJavaLibs target, rather than writing this information to a file and expecting 'gradlew' to process it correctly.
Developers like API compatibility; it helps ensure that their
investment in our platform isn't a waste of time.
Add `tests/api-compatibility` and a new
`make run-api-compatibility-tests` target, part of
`make run-all-tests`, which compares the API of the assemblies in the
current build tree against a "known good" API description maintained
in `tests/api-compatibility/reference/*.xml.gz`, one `.xml.gz` file
per assembly that we are interested in.
The new [`xamarin-android-api-compatibility`][0] submodule contains
the current API description and Make targets to check and update the
API description. `xamarin-android-api-compatibility` uses the
utilities `mono-api-info` and `mono-api-html` to generate and compare
the API descriptions.
A submodule is used because the API descriptions can be quite large --
Mono.Android.xml is currently 54MB -- and we don't want the change
history on these files to "clog up" the xamarin-android repo.
[0]: https://github.com/xamarin/xamarin-android-api-compatibility
Fix a [build][0] [break][1]:
Executing: ./gradlew assembleDebug --stacktrace
...
The android gradle plugin version 2.4.0-alpha3 is too old, please update to the latest version.
To override this check from the command line please set the ANDROID_DAILY_OVERRIDE environment variable to "ea6ce2cbbbfb0e0a68b85eb08916733d4367c4dd"
FAILURE: Build failed with an exception
For a change, this break on Jenkins wasn't *directly* caused by a
commit; it was *indirectly* caused by commit 571546a1, which specified
`com.android.tools.build:gradle:2.4.0-alpha3`.
Turns Out™, `gradle:2.4.0-alpha3` has a builtin "expiration date",
*presumably* of 2017-Apr-30, meaning that when you build after the
expiration date, it doesn't actually build.
The result is the above error from `gradlew assembleDebug`.
The fix? Don't use preview packages if they can be avoided. The
`gradle:2.3.0` package appears to work Just Fine™, with the added
benefit that it's *not* a preview package.
[0]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/371/
[1]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/371/consoleText
First step towards support for Android-O Preview API.
The changes are big due to the structural changes in Android SDK,
particularly that "android" command line tool is gone and they had to
be rewritten. Samples that depended on "create" or "update" command
had to be checked in as already-created state so that they don't have
to bring further dependencies.
Changes in the library (Mono.Android) itself is not very big at all.
`src/Mono.Android/Profiles/api-O.xml.in` comes from API-O DP 1's
`android.jar`.
@xmcclure and I just spent *hours* trying to figure out why a
Xamarin.Android unit test was failing on her device, but nowhere else,
and -- further! -- how when she added *new* tests to the
`Xamarin.Android.JcwGen_Tests` package, the new tests and new debug
messages would never appear on `adb logcat`.
The result? An old install. *Apparently*,
adb install -r bin/TestDebug/Xamarin.Android.JcwGen_Tests-Signed.apk
wasn't actually installing updated file contents.
Manually uninstalling the `Xamarin.Android.JcwGen_Tests` package and
installing a new `Xamarin.Android.JcwGen_Tests-Signed.apk` resulted in
all tests passing, as expected.
What this means *to me* is that `adb install -r` *can't be trusted*.
We pulled our hair out *for hours* trying to figure out why various
things didn't appear to work at all, and nothing worked because we
were never getting the new app on her device.
(Insert fuming here.)
Consequently, *avoid* `adb install -r`. Instead, update the
`$(RunApkTestsDependsOn)` property so that we always call the
`UndeployUnitTestApks` target before calling the `DeployUnitTestApks`
target, and update the `DeployUnitTestApks` target to use "normal"
`adb install` instead of `adb install -r`.