diff --git a/.external b/.external index 49e9c478676..8f7749a446e 100644 --- a/.external +++ b/.external @@ -1 +1 @@ -xamarin/monodroid:main@905441a990d7daf720bdd4fc2f333fed5be28274 +xamarin/monodroid:main@e13723e701307f9f6966d4b309c3eba10a741694 diff --git a/Directory.Build.props b/Directory.Build.props index 35a518fb201..d01d6648f8e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -36,7 +36,7 @@ * Bump first digit of the patch version for feature releases (and reset the first two digits to 0) --> 34.99.0 - preview.2 + preview.3 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1a4130af0be..566089db986 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,24 +1,24 @@ - + https://github.com/dotnet/installer - fb7b9a4b9e578fa8c9f5fb67e22daf4b0d22668e + d070660282eb5f78497310f77093638744112e03 - + https://github.com/dotnet/runtime - d40c654c274fe4f4afe66328f0599130f3eb2ea6 + 99b76018b6e4edc4ce185dd5f3c5697c6941d88e - + https://github.com/dotnet/runtime - d40c654c274fe4f4afe66328f0599130f3eb2ea6 + 99b76018b6e4edc4ce185dd5f3c5697c6941d88e - + https://github.com/dotnet/emsdk - 687be2a32a302aaade82380c0eaafa5af85fb4da + 2d3f1fe4807a21879cedba9d3fde8cd329fb17f2 - + https://github.com/dotnet/cecil - b8c2293cd1cbd9d0fe6f32d7b5befbd526b5a175 + 61250b0ed403b3f9b69a33f7d8f66f311338d6a1 diff --git a/eng/Versions.props b/eng/Versions.props index ea4799ef67c..6bf62dc7325 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,15 +1,15 @@ - 9.0.100-preview.2.24106.6 - 9.0.0-preview.2.24080.1 - 9.0.0-preview.2.24080.1 + 9.0.100-preview.3.24126.2 + 9.0.0-preview.2.24123.1 + 9.0.0-preview.2.24123.1 7.0.0-beta.22103.1 7.0.0-beta.22103.1 - 9.0.0-preview.2.24076.1 + 9.0.0-preview.2.24121.1 $(MicrosoftNETWorkloadEmscriptenCurrentManifest90100TransportVersion) 7.0.100-rc.1.22410.7 - 0.11.4-alpha.24065.1 + 0.11.4-alpha.24119.1 $(MicrosoftNETCoreAppRefPackageVersion) diff --git a/external/Java.Interop b/external/Java.Interop index c825dcad8e7..14a9470176b 160000 --- a/external/Java.Interop +++ b/external/Java.Interop @@ -1 +1 @@ -Subproject commit c825dcad8e7fe2e1ba5846a592a02f6a578db991 +Subproject commit 14a9470176b314fe521479fc75f6d9dd919abb56 diff --git a/external/xamarin-android-tools b/external/xamarin-android-tools index a698a33aa4f..37d79c9dcdf 160000 --- a/external/xamarin-android-tools +++ b/external/xamarin-android-tools @@ -1 +1 @@ -Subproject commit a698a33aa4ffcaac90b54caf5e77236d57b0cf9e +Subproject commit 37d79c9dcdf738a181084b0b5890877128d75f1e diff --git a/src/Mono.Android/Android.Graphics/Color.cs b/src/Mono.Android/Android.Graphics/Color.cs index bf57968663c..97a46fd5b11 100644 --- a/src/Mono.Android/Android.Graphics/Color.cs +++ b/src/Mono.Android/Android.Graphics/Color.cs @@ -395,11 +395,18 @@ public static void RGBToHSV (int red, int green, int blue, float[] hsv) public class ColorValueMarshaler : JniValueMarshaler { + const DynamicallyAccessedMemberTypes ConstructorsAndInterfaces = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.Interfaces; + const string ExpressionRequiresUnreferencedCode = "System.Linq.Expression usage may trim away required code."; + public override Type MarshalType { get { return typeof (int); } } - public override Color CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override Color CreateGenericValue ( + ref JniObjectReference reference, + JniObjectReferenceOptions options, + [DynamicallyAccessedMembers (ConstructorsAndInterfaces)] + Type targetType) { throw new NotImplementedException (); } @@ -414,6 +421,7 @@ public override void DestroyGenericArgumentState (Color value, ref JniValueMarsh throw new NotImplementedException (); } + [RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)] public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type targetType) { var c = typeof (Color).GetConstructor (new[]{typeof (int)})!; @@ -424,6 +432,7 @@ public override Expression CreateParameterToManagedExpression (JniValueMarshaler return v; } + [RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)] public override Expression CreateParameterFromManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize) { var r = Expression.Variable (MarshalType, sourceValue.Name + "_p"); @@ -433,6 +442,7 @@ public override Expression CreateParameterFromManagedExpression (JniValueMarshal return r; } + [RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)] public override Expression CreateReturnValueFromManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue) { return CreateParameterFromManagedExpression (context, sourceValue, 0); diff --git a/src/Mono.Android/Android.Runtime/IJavaObjectValueMarshaler.cs b/src/Mono.Android/Android.Runtime/IJavaObjectValueMarshaler.cs index f5cab61ec1d..89436ab2b08 100644 --- a/src/Mono.Android/Android.Runtime/IJavaObjectValueMarshaler.cs +++ b/src/Mono.Android/Android.Runtime/IJavaObjectValueMarshaler.cs @@ -10,9 +10,16 @@ namespace Android.Runtime { sealed class IJavaObjectValueMarshaler : JniValueMarshaler { + const DynamicallyAccessedMemberTypes ConstructorsAndInterfaces = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.Interfaces; + const string ExpressionRequiresUnreferencedCode = "System.Linq.Expression usage may trim away required code."; + internal static IJavaObjectValueMarshaler Instance = new IJavaObjectValueMarshaler (); - public override IJavaObject CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType) + public override IJavaObject CreateGenericValue ( + ref JniObjectReference reference, + JniObjectReferenceOptions options, + [DynamicallyAccessedMembers (ConstructorsAndInterfaces)] + Type? targetType) { throw new NotImplementedException (); } @@ -27,6 +34,7 @@ public override void DestroyGenericArgumentState ([AllowNull]IJavaObject value, throw new NotImplementedException (); } + [RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)] public override Expression CreateReturnValueFromManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue) { return Expression.Call ( @@ -36,6 +44,7 @@ public override Expression CreateReturnValueFromManagedExpression (JniValueMarsh sourceValue); } + [RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)] public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type? targetType) { var r = Expression.Variable (targetType, sourceValue.Name + "_val"); diff --git a/src/Mono.Android/System.Drawing/PointConverter.cs b/src/Mono.Android/System.Drawing/PointConverter.cs index 0255e55c87e..98a791cf951 100644 --- a/src/Mono.Android/System.Drawing/PointConverter.cs +++ b/src/Mono.Android/System.Drawing/PointConverter.cs @@ -30,6 +30,7 @@ using System.Collections; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.ComponentModel.Design.Serialization; using System.Runtime.CompilerServices; @@ -133,6 +134,7 @@ public override bool GetCreateInstanceSupported (ITypeDescriptorContext context) return true; } + [RequiresUnreferencedCode ("The Type of value cannot be statically discovered.")] public override PropertyDescriptorCollection? GetProperties ( ITypeDescriptorContext context, object value, Attribute[] attributes) diff --git a/src/Mono.Android/System.Drawing/RectangleConverter.cs b/src/Mono.Android/System.Drawing/RectangleConverter.cs index 364784f495f..053f07882af 100644 --- a/src/Mono.Android/System.Drawing/RectangleConverter.cs +++ b/src/Mono.Android/System.Drawing/RectangleConverter.cs @@ -31,6 +31,7 @@ using System.ComponentModel; using System.Collections; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text; using System.ComponentModel.Design.Serialization; @@ -147,6 +148,7 @@ public override bool GetCreateInstanceSupported (ITypeDescriptorContext context) return true; } + [RequiresUnreferencedCode ("The Type of value cannot be statically discovered.")] public override PropertyDescriptorCollection? GetProperties ( ITypeDescriptorContext context, object value, Attribute[] attributes) diff --git a/src/Mono.Android/System.Drawing/SizeConverter.cs b/src/Mono.Android/System.Drawing/SizeConverter.cs index 53fe055733c..f60b57442b1 100644 --- a/src/Mono.Android/System.Drawing/SizeConverter.cs +++ b/src/Mono.Android/System.Drawing/SizeConverter.cs @@ -31,6 +31,7 @@ using System.Collections; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.ComponentModel.Design.Serialization; using System.Reflection; @@ -135,6 +136,7 @@ public override bool GetCreateInstanceSupported (ITypeDescriptorContext context) return true; } + [RequiresUnreferencedCode ("The Type of value cannot be statically discovered.")] public override PropertyDescriptorCollection? GetProperties ( ITypeDescriptorContext context, object value, Attribute[] attributes) diff --git a/src/Mono.Android/System.Drawing/SizeFConverter.cs b/src/Mono.Android/System.Drawing/SizeFConverter.cs index 8933839fba2..fb2e81fce0f 100644 --- a/src/Mono.Android/System.Drawing/SizeFConverter.cs +++ b/src/Mono.Android/System.Drawing/SizeFConverter.cs @@ -32,6 +32,7 @@ using System; using System.Collections; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.ComponentModel.Design.Serialization; using System.Reflection; @@ -118,6 +119,7 @@ public override bool GetCreateInstanceSupported (ITypeDescriptorContext context) return true; } + [RequiresUnreferencedCode ("The Type of value cannot be statically discovered.")] public override PropertyDescriptorCollection? GetProperties (ITypeDescriptorContext context, object value, Attribute[] attributes) { if (value is SizeF) diff --git a/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs b/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs index 83e858e1a62..f12317c1ead 100644 --- a/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs +++ b/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs @@ -313,14 +313,9 @@ protected virtual Task SetupRequest (HttpRequestMessage request, HttpURLConnecti object? GetUnderlyingHandler () { var fieldName = "_nativeHandler"; - FieldInfo? field = null; - - for (var type = GetType (); type != null; type = type.BaseType) { - field = type.GetField (fieldName, BindingFlags.Instance | BindingFlags.NonPublic); - if (field != null) - break; - } - + const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic; + FieldInfo? field = typeof (HttpClientHandler).GetField (fieldName, flags) ?? + typeof (HttpMessageHandler).GetField (fieldName, flags); if (field == null) { throw new InvalidOperationException ($"Field '{fieldName}' is missing from type '{GetType ()}'."); } diff --git a/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs b/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs index 44883640487..26645e6fdcb 100644 --- a/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs +++ b/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs @@ -536,30 +536,29 @@ protected virtual async Task WriteRequestContentToOutput (HttpRequestMessage req if (request.Content is null) return; - using (var stream = await request.Content.ReadAsStreamAsync ().ConfigureAwait (false)) { - await stream.CopyToAsync(httpConnection.OutputStream!, 4096, cancellationToken).ConfigureAwait(false); - - // - // Rewind the stream to beginning in case the HttpContent implementation - // will be accessed again (e.g. after redirect) and it keeps its stream - // open behind the scenes instead of recreating it on the next call to - // ReadAsStreamAsync. If we don't rewind it, the ReadAsStreamAsync - // call above will throw an exception as we'd be attempting to read an - // already "closed" stream (that is one whose Position is set to its - // end). - // - // This is not a perfect solution since the HttpContent may do weird - // things in its implementation, but it's better than copying the - // content into a buffer since we have no way of knowing how the data is - // read or generated and also we don't want to keep potentially large - // amounts of data in memory (which would happen if we read the content - // into a byte[] buffer and kept it cached for re-use on redirect). - // - // See https://bugzilla.xamarin.com/show_bug.cgi?id=55477 - // - if (stream.CanSeek) - stream.Seek (0, SeekOrigin.Begin); - } + var stream = await request.Content.ReadAsStreamAsync ().ConfigureAwait (false); + await stream.CopyToAsync(httpConnection.OutputStream!, 4096, cancellationToken).ConfigureAwait(false); + + // + // Rewind the stream to beginning in case the HttpContent implementation + // will be accessed again (e.g. after redirect) and it keeps its stream + // open behind the scenes instead of recreating it on the next call to + // ReadAsStreamAsync. If we don't rewind it, the ReadAsStreamAsync + // call above will throw an exception as we'd be attempting to read an + // already "closed" stream (that is one whose Position is set to its + // end). + // + // This is not a perfect solution since the HttpContent may do weird + // things in its implementation, but it's better than copying the + // content into a buffer since we have no way of knowing how the data is + // read or generated and also we don't want to keep potentially large + // amounts of data in memory (which would happen if we read the content + // into a byte[] buffer and kept it cached for re-use on redirect). + // + // See https://bugzilla.xamarin.com/show_bug.cgi?id=55477 + // + if (stream.CanSeek) + stream.Seek (0, SeekOrigin.Begin); } internal Task WriteRequestContentToOutputInternal (HttpRequestMessage request, HttpURLConnection httpConnection, CancellationToken cancellationToken) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs index 20e569c618c..bf69140c390 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AotTests.cs @@ -111,19 +111,17 @@ public void BuildBasicApplicationReleaseProfiledAotWithoutDefaultProfile () } [Test] - [TestCase ("テスト", false, false, true)] - [TestCase ("テスト", true, true, false)] - [TestCase ("テスト", true, false, true)] - [TestCase ("随机生成器", false, false, true)] - [TestCase ("随机生成器", true, true, false)] - [TestCase ("随机生成器", true, false, true)] - [TestCase ("中国", false, false, true)] - [TestCase ("中国", true, true, false)] - [TestCase ("中国", true, false, true)] - public void BuildAotApplicationWithSpecialCharactersInProject (string testName, bool isRelease, bool aot, bool expectedResult) + [TestCase ("テスト", false, false)] + [TestCase ("テスト", true, true)] + [TestCase ("テスト", true, false)] + [TestCase ("随机生成器", false, false)] + [TestCase ("随机生成器", true, true)] + [TestCase ("随机生成器", true, false)] + [TestCase ("中国", false, false)] + [TestCase ("中国", true, true)] + [TestCase ("中国", true, false)] + public void BuildAotApplicationWithSpecialCharactersInProject (string testName, bool isRelease, bool aot) { - if (!IsWindows) - expectedResult = true; var rootPath = Path.Combine (Root, "temp", TestName); var proj = new XamarinAndroidApplicationProject () { ProjectName = testName, @@ -132,13 +130,7 @@ public void BuildAotApplicationWithSpecialCharactersInProject (string testName, }; proj.SetAndroidSupportedAbis ("armeabi-v7a", "arm64-v8a", "x86", "x86_64"); using (var builder = CreateApkBuilder (Path.Combine (rootPath, proj.ProjectName))){ - builder.ThrowOnBuildFailure = false; - Assert.AreEqual (expectedResult, builder.Build (proj), "Build should have succeeded."); - if (!expectedResult) { - var aotFailed = builder.LastBuildOutput.ContainsText ("Precompiling failed"); - var aapt2Failed = builder.LastBuildOutput.ContainsText ("APT2265"); - Assert.IsTrue (aotFailed || aapt2Failed, "Error APT2265 or an AOT error should have been raised."); - } + Assert.IsTrue (builder.Build (proj), "Build should have succeeded."); } } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs index ad00180380e..601406c0748 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs @@ -395,7 +395,6 @@ public void CopyNuGetConfig (string relativeDirectory) /// /// Updates a NuGet.config based on sources in ExtraNuGetConfigSources - /// If target framework is not the latest or default, sources are added for previous releases /// protected void AddNuGetConfigSources (string nugetConfigPath) { @@ -415,14 +414,8 @@ protected void AddNuGetConfigSources (string nugetConfigPath) ExtraNuGetConfigSources = new List (); } - if (TargetFramework?.IndexOf ("net8.0", StringComparison.OrdinalIgnoreCase) != -1 - || TargetFrameworks?.IndexOf ("net8.0", StringComparison.OrdinalIgnoreCase) != -1) { - ExtraNuGetConfigSources.Add ("https://api.nuget.org/v3/index.json"); - ExtraNuGetConfigSources.Add ("https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json"); - } - int sourceIndex = 0; - foreach (var source in ExtraNuGetConfigSources) { + foreach (var source in ExtraNuGetConfigSources.Distinct ()) { var sourceElement = new XElement ("add"); sourceElement.SetAttributeValue ("key", $"testsource{++sourceIndex}"); sourceElement.SetAttributeValue ("value", source); diff --git a/src/r8/build.gradle b/src/r8/build.gradle index 58ce928562d..e95e9ce1a52 100644 --- a/src/r8/build.gradle +++ b/src/r8/build.gradle @@ -15,7 +15,7 @@ repositories { } dependencies { - implementation 'com.android.tools:r8:8.2.42' + implementation 'com.android.tools:r8:8.2.47' } jar { diff --git a/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs b/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs index 96f66778ef3..b71ee2893da 100644 --- a/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs +++ b/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs @@ -98,6 +98,31 @@ async Task DoDecompression (string urlPath, string encoding, string jsonFi return true; } + [Test] + public async Task DoesNotDisposeContentStream() + { + using var listener = new HttpListener (); + listener.Prefixes.Add ("http://+:47663/"); + listener.Start (); + listener.BeginGetContext (ar => { + var ctx = listener.EndGetContext (ar); + ctx.Response.StatusCode = 204; + ctx.Response.ContentLength64 = 0; + ctx.Response.Close (); + }, null); + + var jsonContent = new StringContent ("hello"); + var request = new HttpRequestMessage (HttpMethod.Post, "http://localhost:47663/") { Content = jsonContent }; + + var response = await new HttpClient (new AndroidMessageHandler ()).SendAsync (request); + Assert.True (response.IsSuccessStatusCode); + + var contentValue = await jsonContent.ReadAsStringAsync (); + Assert.AreEqual ("hello", contentValue); + + listener.Close (); + } + [Test] public async Task ServerCertificateCustomValidationCallback_ApproveRequest () {