diff --git a/src/Mono.Android/Mono.Android.csproj b/src/Mono.Android/Mono.Android.csproj
index a5c011b0700..9e3d8a6c3fd 100644
--- a/src/Mono.Android/Mono.Android.csproj
+++ b/src/Mono.Android/Mono.Android.csproj
@@ -367,6 +367,7 @@
+
diff --git a/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs b/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs
index 40fe7d85965..b31a8a804d1 100644
--- a/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs
+++ b/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs
@@ -157,7 +157,15 @@ public CookieContainer CookieContainer
public bool CheckCertificateRevocationList { get; set; } = false;
- public Func ServerCertificateCustomValidationCallback { get; set; }
+ X509TrustManagerWithValidationCallback.Helper? _callbackTrustManagerHelper = null;
+
+ public Func? ServerCertificateCustomValidationCallback
+ {
+ get => _callbackTrustManagerHelper?.Callback;
+ set {
+ _callbackTrustManagerHelper = value != null ? new X509TrustManagerWithValidationCallback.Helper (value) : null;
+ }
+ }
// See: https://developer.android.com/reference/javax/net/ssl/SSLSocket#protocols
public SslProtocols SslProtocols { get; set; } =
@@ -199,7 +207,7 @@ public int MaxAutomaticRedirections
/// If the website requires authentication, this property will contain data about each scheme supported
/// by the server after the response. Note that unauthorized request will return a valid response - you
/// need to check the status code and and (re)configure AndroidMessageHandler instance accordingly by providing
- /// both the credentials and the authentication scheme by setting the
+ /// both the credentials and the authentication scheme by setting the
/// property. If AndroidMessageHandler is not able to detect the kind of authentication scheme it will store an
/// instance of with its property
/// set to AuthenticationScheme.Unsupported and the application will be responsible for providing an
@@ -939,7 +947,7 @@ void AppendEncoding (string encoding, ref List ? list)
// SSL context must be set up as soon as possible, before adding any content or
// headers. Otherwise Java won't use the socket factory
- SetupSSL (httpConnection as HttpsURLConnection);
+ SetupSSL (httpConnection as HttpsURLConnection, request);
if (request.Content != null)
AddHeaders (httpConnection, request.Content.Headers);
AddHeaders (httpConnection, request.Headers);
@@ -997,7 +1005,7 @@ void AppendEncoding (string encoding, ref List ? list)
internal SSLSocketFactory? ConfigureCustomSSLSocketFactoryInternal (HttpsURLConnection connection)
=> ConfigureCustomSSLSocketFactoryInternal (connection);
- void SetupSSL (HttpsURLConnection? httpsConnection)
+ void SetupSSL (HttpsURLConnection? httpsConnection, HttpRequestMessage requestMessage)
{
if (httpsConnection == null)
return;
@@ -1017,35 +1025,48 @@ void SetupSSL (HttpsURLConnection? httpsConnection)
}
#endif
- var keyStore = KeyStore.GetInstance (KeyStore.DefaultType);
- keyStore?.Load (null, null);
- bool gotCerts = TrustedCerts?.Count > 0;
- if (gotCerts) {
- for (int i = 0; i < TrustedCerts!.Count; i++) {
- Certificate cert = TrustedCerts [i];
- if (cert == null)
- continue;
- keyStore?.SetCertificateEntry ($"ca{i}", cert);
- }
- }
+ var keyStore = InitializeKeyStore (out bool gotCerts);
keyStore = ConfigureKeyStore (keyStore);
var kmf = ConfigureKeyManagerFactory (keyStore);
var tmf = ConfigureTrustManagerFactory (keyStore);
if (tmf == null) {
- // If there are no certs and no trust manager factory, we can't use a custom manager
- // because it will cause all the HTTPS requests to fail because of unverified trust
- // chain
- if (!gotCerts)
+ // If there are no trusted certs, no custom trust manager factory or custom certificate validation callback
+ // there is no point in changing the behavior of the default SSL socket factory
+ if (!gotCerts && _callbackTrustManagerHelper == null)
return;
tmf = TrustManagerFactory.GetInstance (TrustManagerFactory.DefaultAlgorithm);
- tmf?.Init (keyStore);
+ tmf?.Init (gotCerts ? keyStore : null); // only use the custom key store if the user defined any trusted certs
+ }
+
+ ITrustManager[]? trustManagers = tmf?.GetTrustManagers ();
+
+ if (_callbackTrustManagerHelper != null) {
+ trustManagers = _callbackTrustManagerHelper.Inject (trustManagers, requestMessage);
}
var context = SSLContext.GetInstance ("TLS");
- context?.Init (kmf?.GetKeyManagers (), tmf?.GetTrustManagers (), null);
+ context?.Init (kmf?.GetKeyManagers (), trustManagers, null);
httpsConnection.SSLSocketFactory = context?.SocketFactory;
+
+ KeyStore? InitializeKeyStore (out bool gotCerts)
+ {
+ var keyStore = KeyStore.GetInstance (KeyStore.DefaultType);
+ keyStore?.Load (null, null);
+ gotCerts = TrustedCerts?.Count > 0;
+
+ if (gotCerts) {
+ for (int i = 0; i < TrustedCerts!.Count; i++) {
+ Certificate cert = TrustedCerts [i];
+ if (cert == null)
+ continue;
+ keyStore?.SetCertificateEntry ($"ca{i}", cert);
+ }
+ }
+
+ return keyStore;
+ }
}
void HandlePreAuthentication (HttpURLConnection httpConnection)
@@ -1116,4 +1137,4 @@ void SetupRequestBody (HttpURLConnection httpConnection, HttpRequestMessage requ
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Mono.Android/Xamarin.Android.Net/X509TrustManagerWithValidationCallback.cs b/src/Mono.Android/Xamarin.Android.Net/X509TrustManagerWithValidationCallback.cs
new file mode 100644
index 00000000000..7eafe3ebd2e
--- /dev/null
+++ b/src/Mono.Android/Xamarin.Android.Net/X509TrustManagerWithValidationCallback.cs
@@ -0,0 +1,96 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
+
+using Javax.Net.Ssl;
+
+using JavaCertificateException = Java.Security.Cert.CertificateException;
+using JavaX509Certificate = Java.Security.Cert.X509Certificate;
+
+namespace Xamarin.Android.Net
+{
+ internal sealed class X509TrustManagerWithValidationCallback : Java.Lang.Object, IX509TrustManager
+ {
+ internal sealed class Helper
+ {
+ public Func Callback { get; }
+
+ public Helper (Func callback)
+ {
+ Callback = callback;
+ }
+
+ public ITrustManager[] Inject (
+ ITrustManager[]? trustManagers,
+ HttpRequestMessage requestMessage)
+ {
+ IX509TrustManager? x509TrustManager = trustManagers?.OfType ().FirstOrDefault ();
+ IEnumerable otherTrustManagers = trustManagers?.Where (manager => manager != x509TrustManager) ?? Enumerable.Empty ();
+ var trustManagerWithCallback = new X509TrustManagerWithValidationCallback (x509TrustManager, requestMessage, Callback);
+ return otherTrustManagers.Prepend (trustManagerWithCallback).ToArray ();
+ }
+ }
+
+ private readonly IX509TrustManager? _internalTrustManager;
+ private readonly HttpRequestMessage _request;
+ private readonly Func _serverCertificateCustomValidationCallback;
+
+ private X509TrustManagerWithValidationCallback (
+ IX509TrustManager? internalTrustManager,
+ HttpRequestMessage request,
+ Func serverCertificateCustomValidationCallback)
+ {
+ _request = request;
+ _internalTrustManager = internalTrustManager;
+ _serverCertificateCustomValidationCallback = serverCertificateCustomValidationCallback;
+ }
+
+ public void CheckServerTrusted (JavaX509Certificate[] javaChain, string authType)
+ {
+ var sslPolicyErrors = SslPolicyErrors.None;
+ var certificates = ConvertCertificates (javaChain);
+
+ try {
+ _internalTrustManager?.CheckServerTrusted (javaChain, authType);
+ } catch (JavaCertificateException) {
+ sslPolicyErrors |= SslPolicyErrors.RemoteCertificateChainErrors;
+ }
+
+ X509Certificate2? certificate = certificates.FirstOrDefault ();
+ using X509Chain chain = CreateChain (certificates);
+
+ if (certificate == null) {
+ sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable;
+ }
+
+ if (!_serverCertificateCustomValidationCallback (_request, certificate, chain, sslPolicyErrors)) {
+ throw new JavaCertificateException ("The remote certificate was rejected by the provided RemoteCertificateValidationCallback.");
+ }
+ }
+
+ public void CheckClientTrusted (JavaX509Certificate[] chain, string authType)
+ => _internalTrustManager?.CheckClientTrusted (chain, authType);
+
+ public JavaX509Certificate[] GetAcceptedIssuers ()
+ => _internalTrustManager?.GetAcceptedIssuers () ?? Array.Empty ();
+
+ private static X509Chain CreateChain (X509Certificate2[] certificates)
+ {
+ // the chain initialization is based on dotnet/runtime implementation in System.Net.Security.SecureChannel
+ var chain = new X509Chain ();
+
+ chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
+ chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
+
+ chain.ChainPolicy.ExtraStore.AddRange (certificates);
+
+ return chain;
+ }
+
+ private static X509Certificate2[] ConvertCertificates (JavaX509Certificate[] certificates)
+ => certificates.Select (cert => new X509Certificate2 (cert.GetEncoded ()!)).ToArray ();
+ }
+}
diff --git a/src/Xamarin.Android.Build.Tasks/Resources/proguard_xamarin.cfg b/src/Xamarin.Android.Build.Tasks/Resources/proguard_xamarin.cfg
index 914ef686ac2..881353bf906 100644
--- a/src/Xamarin.Android.Build.Tasks/Resources/proguard_xamarin.cfg
+++ b/src/Xamarin.Android.Build.Tasks/Resources/proguard_xamarin.cfg
@@ -15,6 +15,7 @@
-keep class opentk_1_0.platform.android.AndroidGameView { *; (...); }
-keep class opentk_1_0.GameViewBase { *; (...); }
-keep class com.xamarin.java_interop.ManagedPeer { *; (...); }
+-keep class xamarin.android.net.X509TrustManagerWithValidationCallback { *; (...); }
-keep class android.runtime.** { (...); }
-keep class assembly_mono_android.android.runtime.** { (...); }
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc
index 3cbcb3bb767..11037595fc9 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc
@@ -5,37 +5,37 @@
"Size": 3032
},
"assemblies/Java.Interop.dll": {
- "Size": 55106
+ "Size": 55099
},
"assemblies/Mono.Android.dll": {
- "Size": 88461
+ "Size": 88852
},
"assemblies/rc.bin": {
"Size": 1083
},
"assemblies/System.Linq.dll": {
- "Size": 10120
+ "Size": 10112
},
"assemblies/System.Private.CoreLib.dll": {
- "Size": 519314
+ "Size": 519255
},
"assemblies/System.Runtime.CompilerServices.Unsafe.dll": {
"Size": 1165
},
"assemblies/System.Runtime.dll": {
- "Size": 2374
+ "Size": 2369
},
"assemblies/UnnamedProject.dll": {
- "Size": 3546
+ "Size": 3543
},
"classes.dex": {
- "Size": 345328
+ "Size": 344840
},
"lib/arm64-v8a/libmonodroid.so": {
- "Size": 382304
+ "Size": 382480
},
"lib/arm64-v8a/libmonosgen-2.0.so": {
- "Size": 3192432
+ "Size": 3176080
},
"lib/arm64-v8a/libSystem.IO.Compression.Native.so": {
"Size": 776216
@@ -47,7 +47,7 @@
"Size": 150032
},
"lib/arm64-v8a/libxamarin-app.so": {
- "Size": 9424
+ "Size": 9328
},
"META-INF/BNDLTOOL.RSA": {
"Size": 1213
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleLegacy.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleLegacy.apkdesc
index 33a48ec8ce0..82b072836e9 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleLegacy.apkdesc
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleLegacy.apkdesc
@@ -5,35 +5,35 @@
"Size": 2604
},
"assemblies/Java.Interop.dll": {
- "Size": 67956
+ "Size": 67947
},
"assemblies/Mono.Android.dll": {
- "Size": 256630
+ "Size": 257171
},
"assemblies/mscorlib.dll": {
- "Size": 769015
+ "Size": 769010
},
"assemblies/System.Core.dll": {
- "Size": 28199
+ "Size": 28190
},
"assemblies/System.dll": {
- "Size": 9180
+ "Size": 9178
},
"assemblies/UnnamedProject.dll": {
- "Size": 2881
+ "Size": 2871
},
"classes.dex": {
- "Size": 347796
+ "Size": 349528
},
"lib/arm64-v8a/libmono-btls-shared.so": {
"Size": 1613872
},
+ "lib/arm64-v8a/libmonodroid.so": {
+ "Size": 296448
+ },
"lib/arm64-v8a/libmono-native.so": {
"Size": 750976
},
- "lib/arm64-v8a/libmonodroid.so": {
- "Size": 296192
- },
"lib/arm64-v8a/libmonosgen-2.0.so": {
"Size": 4030448
},
@@ -41,7 +41,7 @@
"Size": 65512
},
"lib/arm64-v8a/libxamarin-app.so": {
- "Size": 19960
+ "Size": 19864
},
"META-INF/ANDROIDD.RSA": {
"Size": 1213
@@ -74,5 +74,5 @@
"Size": 1724
}
},
- "PackageSize": 4011732
+ "PackageSize": 4015828
}
\ No newline at end of file
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc
index f3acfe04246..aab3f1b77d5 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsDotNet.apkdesc
@@ -5,184 +5,184 @@
"Size": 3568
},
"assemblies/FormsViewGroup.dll": {
- "Size": 7247
+ "Size": 7240
},
"assemblies/Java.Interop.dll": {
- "Size": 62017
+ "Size": 62048
},
"assemblies/Mono.Android.dll": {
- "Size": 442008
+ "Size": 445340
},
"assemblies/mscorlib.dll": {
- "Size": 3803
+ "Size": 3799
},
"assemblies/netstandard.dll": {
- "Size": 5503
+ "Size": 5498
},
"assemblies/rc.bin": {
"Size": 1083
},
"assemblies/System.Collections.Concurrent.dll": {
- "Size": 11230
+ "Size": 11226
},
"assemblies/System.Collections.dll": {
- "Size": 16741
+ "Size": 16734
},
"assemblies/System.Collections.NonGeneric.dll": {
- "Size": 8443
+ "Size": 8434
},
"assemblies/System.ComponentModel.dll": {
- "Size": 1965
+ "Size": 1960
},
"assemblies/System.ComponentModel.Primitives.dll": {
- "Size": 2569
+ "Size": 2563
},
"assemblies/System.ComponentModel.TypeConverter.dll": {
- "Size": 5970
+ "Size": 5967
},
"assemblies/System.Console.dll": {
- "Size": 6532
+ "Size": 6526
},
"assemblies/System.Core.dll": {
- "Size": 1932
+ "Size": 1928
},
"assemblies/System.Diagnostics.TraceSource.dll": {
- "Size": 6761
+ "Size": 6754
},
"assemblies/System.dll": {
- "Size": 2279
+ "Size": 2274
},
"assemblies/System.Drawing.dll": {
- "Size": 1961
+ "Size": 1956
},
"assemblies/System.Drawing.Primitives.dll": {
- "Size": 12206
+ "Size": 12197
},
"assemblies/System.IO.Compression.dll": {
- "Size": 17221
+ "Size": 17215
},
"assemblies/System.IO.IsolatedStorage.dll": {
- "Size": 10569
+ "Size": 10568
},
"assemblies/System.Linq.dll": {
- "Size": 19480
+ "Size": 19471
},
"assemblies/System.Linq.Expressions.dll": {
- "Size": 182084
+ "Size": 182073
},
"assemblies/System.Net.Http.dll": {
- "Size": 65842
+ "Size": 65836
},
"assemblies/System.Net.Primitives.dll": {
- "Size": 22368
+ "Size": 22364
},
"assemblies/System.Net.Requests.dll": {
- "Size": 3734
+ "Size": 3728
},
"assemblies/System.ObjectModel.dll": {
- "Size": 11974
+ "Size": 11967
},
"assemblies/System.Private.CoreLib.dll": {
- "Size": 757472
+ "Size": 757481
},
"assemblies/System.Private.DataContractSerialization.dll": {
- "Size": 191079
+ "Size": 191077
},
"assemblies/System.Private.Uri.dll": {
- "Size": 43502
+ "Size": 43498
},
"assemblies/System.Private.Xml.dll": {
- "Size": 220183
+ "Size": 220179
},
"assemblies/System.Private.Xml.Linq.dll": {
- "Size": 17099
+ "Size": 17093
},
"assemblies/System.Runtime.CompilerServices.Unsafe.dll": {
"Size": 1216
},
"assemblies/System.Runtime.dll": {
- "Size": 2561
+ "Size": 2557
},
"assemblies/System.Runtime.Serialization.dll": {
- "Size": 1893
+ "Size": 1890
},
"assemblies/System.Runtime.Serialization.Formatters.dll": {
- "Size": 2637
+ "Size": 2630
},
"assemblies/System.Runtime.Serialization.Primitives.dll": {
- "Size": 3943
+ "Size": 3938
},
"assemblies/System.Security.Cryptography.Algorithms.dll": {
- "Size": 6815
+ "Size": 6810
},
"assemblies/System.Security.Cryptography.Primitives.dll": {
- "Size": 2973
+ "Size": 2967
},
"assemblies/System.Text.RegularExpressions.dll": {
- "Size": 76702
+ "Size": 76701
},
"assemblies/System.Xml.dll": {
- "Size": 1782
+ "Size": 1781
},
"assemblies/UnnamedProject.dll": {
- "Size": 117237
+ "Size": 117235
},
"assemblies/Xamarin.AndroidX.Activity.dll": {
- "Size": 6069
+ "Size": 6068
},
"assemblies/Xamarin.AndroidX.AppCompat.AppCompatResources.dll": {
- "Size": 6095
+ "Size": 6091
},
"assemblies/Xamarin.AndroidX.AppCompat.dll": {
- "Size": 112591
+ "Size": 112585
},
"assemblies/Xamarin.AndroidX.CardView.dll": {
- "Size": 6810
+ "Size": 6804
},
"assemblies/Xamarin.AndroidX.CoordinatorLayout.dll": {
- "Size": 16603
+ "Size": 16599
},
"assemblies/Xamarin.AndroidX.Core.dll": {
- "Size": 96722
+ "Size": 96714
},
"assemblies/Xamarin.AndroidX.DrawerLayout.dll": {
- "Size": 14271
+ "Size": 14267
},
"assemblies/Xamarin.AndroidX.Fragment.dll": {
- "Size": 39926
+ "Size": 39925
},
"assemblies/Xamarin.AndroidX.Legacy.Support.Core.UI.dll": {
- "Size": 6133
+ "Size": 6130
},
"assemblies/Xamarin.AndroidX.Lifecycle.Common.dll": {
- "Size": 6592
+ "Size": 6588
},
"assemblies/Xamarin.AndroidX.Lifecycle.LiveData.Core.dll": {
- "Size": 6672
+ "Size": 6668
},
"assemblies/Xamarin.AndroidX.Lifecycle.ViewModel.dll": {
- "Size": 3272
+ "Size": 3269
},
"assemblies/Xamarin.AndroidX.Loader.dll": {
- "Size": 12670
+ "Size": 12666
},
"assemblies/Xamarin.AndroidX.RecyclerView.dll": {
- "Size": 84687
+ "Size": 84678
},
"assemblies/Xamarin.AndroidX.SavedState.dll": {
- "Size": 5077
+ "Size": 5074
},
"assemblies/Xamarin.AndroidX.SwipeRefreshLayout.dll": {
- "Size": 10382
+ "Size": 10375
},
"assemblies/Xamarin.AndroidX.ViewPager.dll": {
- "Size": 17985
+ "Size": 17982
},
"assemblies/Xamarin.Forms.Core.dll": {
"Size": 528450
},
"assemblies/Xamarin.Forms.Platform.Android.dll": {
- "Size": 384997
+ "Size": 384995
},
"assemblies/Xamarin.Forms.Platform.dll": {
"Size": 56878
@@ -191,16 +191,16 @@
"Size": 60774
},
"assemblies/Xamarin.Google.Android.Material.dll": {
- "Size": 40135
+ "Size": 40129
},
"classes.dex": {
- "Size": 3458288
+ "Size": 3457504
},
"lib/arm64-v8a/libmonodroid.so": {
- "Size": 382304
+ "Size": 382480
},
"lib/arm64-v8a/libmonosgen-2.0.so": {
- "Size": 3192432
+ "Size": 3176080
},
"lib/arm64-v8a/libSystem.IO.Compression.Native.so": {
"Size": 776216
@@ -212,7 +212,7 @@
"Size": 150032
},
"lib/arm64-v8a/libxamarin-app.so": {
- "Size": 98624
+ "Size": 98640
},
"META-INF/android.support.design_material.version": {
"Size": 12
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsLegacy.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsLegacy.apkdesc
index b4adbbf5847..0e8e59be373 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsLegacy.apkdesc
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsLegacy.apkdesc
@@ -5,125 +5,125 @@
"Size": 3140
},
"assemblies/FormsViewGroup.dll": {
- "Size": 7215
+ "Size": 7207
},
"assemblies/Java.Interop.dll": {
- "Size": 68921
+ "Size": 68912
},
"assemblies/Mono.Android.dll": {
- "Size": 567161
+ "Size": 568333
},
"assemblies/Mono.Security.dll": {
- "Size": 68433
+ "Size": 68430
},
"assemblies/mscorlib.dll": {
- "Size": 915405
+ "Size": 915391
},
"assemblies/System.Core.dll": {
- "Size": 164045
+ "Size": 164044
},
"assemblies/System.dll": {
- "Size": 388864
+ "Size": 388860
},
"assemblies/System.Drawing.Common.dll": {
- "Size": 12365
+ "Size": 12356
},
"assemblies/System.Net.Http.dll": {
- "Size": 110642
+ "Size": 110637
},
"assemblies/System.Numerics.dll": {
- "Size": 15683
+ "Size": 15681
},
"assemblies/System.Runtime.Serialization.dll": {
- "Size": 186660
+ "Size": 186653
},
"assemblies/System.ServiceModel.Internals.dll": {
- "Size": 26593
+ "Size": 26585
},
"assemblies/System.Xml.dll": {
- "Size": 395657
+ "Size": 395652
},
"assemblies/UnnamedProject.dll": {
- "Size": 116898
+ "Size": 116887
},
"assemblies/Xamarin.AndroidX.Activity.dll": {
- "Size": 7701
+ "Size": 7689
},
"assemblies/Xamarin.AndroidX.AppCompat.AppCompatResources.dll": {
- "Size": 6651
+ "Size": 6640
},
"assemblies/Xamarin.AndroidX.AppCompat.dll": {
- "Size": 125337
+ "Size": 125325
},
"assemblies/Xamarin.AndroidX.CardView.dll": {
- "Size": 7370
+ "Size": 7357
},
"assemblies/Xamarin.AndroidX.CoordinatorLayout.dll": {
- "Size": 18280
+ "Size": 18264
},
"assemblies/Xamarin.AndroidX.Core.dll": {
- "Size": 131939
+ "Size": 131924
},
"assemblies/Xamarin.AndroidX.DrawerLayout.dll": {
- "Size": 15430
+ "Size": 15422
},
"assemblies/Xamarin.AndroidX.Fragment.dll": {
- "Size": 43150
+ "Size": 43130
},
"assemblies/Xamarin.AndroidX.Legacy.Support.Core.UI.dll": {
- "Size": 6716
+ "Size": 6708
},
"assemblies/Xamarin.AndroidX.Lifecycle.Common.dll": {
- "Size": 7071
+ "Size": 7055
},
"assemblies/Xamarin.AndroidX.Lifecycle.LiveData.Core.dll": {
- "Size": 7195
+ "Size": 7186
},
"assemblies/Xamarin.AndroidX.Lifecycle.ViewModel.dll": {
- "Size": 4875
+ "Size": 4862
},
"assemblies/Xamarin.AndroidX.Loader.dll": {
- "Size": 13589
+ "Size": 13578
},
"assemblies/Xamarin.AndroidX.RecyclerView.dll": {
- "Size": 102339
+ "Size": 102322
},
"assemblies/Xamarin.AndroidX.SavedState.dll": {
- "Size": 6283
+ "Size": 6265
},
"assemblies/Xamarin.AndroidX.SwipeRefreshLayout.dll": {
- "Size": 11270
+ "Size": 11261
},
"assemblies/Xamarin.AndroidX.ViewPager.dll": {
- "Size": 19429
+ "Size": 19415
},
"assemblies/Xamarin.Forms.Core.dll": {
- "Size": 524736
+ "Size": 524728
},
"assemblies/Xamarin.Forms.Platform.Android.dll": {
- "Size": 384876
+ "Size": 384861
},
"assemblies/Xamarin.Forms.Platform.dll": {
"Size": 56878
},
"assemblies/Xamarin.Forms.Xaml.dll": {
- "Size": 55801
+ "Size": 55795
},
"assemblies/Xamarin.Google.Android.Material.dll": {
- "Size": 43505
+ "Size": 43489
},
"classes.dex": {
- "Size": 3460636
+ "Size": 3461960
},
"lib/arm64-v8a/libmono-btls-shared.so": {
"Size": 1613872
},
+ "lib/arm64-v8a/libmonodroid.so": {
+ "Size": 296448
+ },
"lib/arm64-v8a/libmono-native.so": {
"Size": 750976
},
- "lib/arm64-v8a/libmonodroid.so": {
- "Size": 296192
- },
"lib/arm64-v8a/libmonosgen-2.0.so": {
"Size": 4030448
},
@@ -131,7 +131,7 @@
"Size": 65512
},
"lib/arm64-v8a/libxamarin-app.so": {
- "Size": 105016
+ "Size": 104920
},
"META-INF/android.support.design_material.version": {
"Size": 12
@@ -145,10 +145,10 @@
"META-INF/androidx.activity_activity.version": {
"Size": 6
},
- "META-INF/androidx.appcompat_appcompat-resources.version": {
+ "META-INF/androidx.appcompat_appcompat.version": {
"Size": 6
},
- "META-INF/androidx.appcompat_appcompat.version": {
+ "META-INF/androidx.appcompat_appcompat-resources.version": {
"Size": 6
},
"META-INF/androidx.arch.core_core-runtime.version": {
@@ -196,10 +196,10 @@
"META-INF/androidx.legacy_legacy-support-v4.version": {
"Size": 6
},
- "META-INF/androidx.lifecycle_lifecycle-livedata-core.version": {
+ "META-INF/androidx.lifecycle_lifecycle-livedata.version": {
"Size": 6
},
- "META-INF/androidx.lifecycle_lifecycle-livedata.version": {
+ "META-INF/androidx.lifecycle_lifecycle-livedata-core.version": {
"Size": 6
},
"META-INF/androidx.lifecycle_lifecycle-runtime.version": {
@@ -235,10 +235,10 @@
"META-INF/androidx.transition_transition.version": {
"Size": 6
},
- "META-INF/androidx.vectordrawable_vectordrawable-animated.version": {
+ "META-INF/androidx.vectordrawable_vectordrawable.version": {
"Size": 6
},
- "META-INF/androidx.vectordrawable_vectordrawable.version": {
+ "META-INF/androidx.vectordrawable_vectordrawable-animated.version": {
"Size": 6
},
"META-INF/androidx.versionedparcelable_versionedparcelable.version": {
@@ -256,12 +256,6 @@
"META-INF/proguard/androidx-annotations.pro": {
"Size": 339
},
- "res/anim-v21/design_bottom_sheet_slide_in.xml": {
- "Size": 616
- },
- "res/anim-v21/design_bottom_sheet_slide_out.xml": {
- "Size": 616
- },
"res/anim/abc_fade_in.xml": {
"Size": 388
},
@@ -358,9 +352,6 @@
"res/anim/exittoright.xml": {
"Size": 468
},
- "res/animator-v21/design_appbar_state_list_animator.xml": {
- "Size": 1216
- },
"res/animator/design_fab_hide_motion_spec.xml": {
"Size": 796
},
@@ -388,38 +379,14 @@
"res/animator/mtrl_fab_transformation_sheet_expand_spec.xml": {
"Size": 1888
},
- "res/color-v21/abc_btn_colored_borderless_text_material.xml": {
- "Size": 464
- },
- "res/color-v23/abc_btn_colored_borderless_text_material.xml": {
- "Size": 500
- },
- "res/color-v23/abc_btn_colored_text_material.xml": {
- "Size": 500
- },
- "res/color-v23/abc_color_highlight_material.xml": {
- "Size": 544
- },
- "res/color-v23/abc_tint_btn_checkable.xml": {
- "Size": 624
- },
- "res/color-v23/abc_tint_default.xml": {
- "Size": 1120
- },
- "res/color-v23/abc_tint_edittext.xml": {
- "Size": 668
- },
- "res/color-v23/abc_tint_seek_thumb.xml": {
- "Size": 500
- },
- "res/color-v23/abc_tint_spinner.xml": {
- "Size": 668
+ "res/animator-v21/design_appbar_state_list_animator.xml": {
+ "Size": 1216
},
- "res/color-v23/abc_tint_switch_track.xml": {
- "Size": 664
+ "res/anim-v21/design_bottom_sheet_slide_in.xml": {
+ "Size": 616
},
- "res/color-v23/design_tint_password_toggle.xml": {
- "Size": 376
+ "res/anim-v21/design_bottom_sheet_slide_out.xml": {
+ "Size": 616
},
"res/color/abc_background_cache_hint_selector_material_dark.xml": {
"Size": 468
@@ -523,10 +490,10 @@
"res/color/mtrl_tabs_colored_ripple_color.xml": {
"Size": 948
},
- "res/color/mtrl_tabs_icon_color_selector_colored.xml": {
+ "res/color/mtrl_tabs_icon_color_selector.xml": {
"Size": 464
},
- "res/color/mtrl_tabs_icon_color_selector.xml": {
+ "res/color/mtrl_tabs_icon_color_selector_colored.xml": {
"Size": 464
},
"res/color/mtrl_tabs_legacy_text_color_selector.xml": {
@@ -544,159 +511,375 @@
"res/color/switch_thumb_material_light.xml": {
"Size": 464
},
- "res/drawable-anydpi-v21/design_ic_visibility_off.xml": {
- "Size": 1144
- },
- "res/drawable-anydpi-v21/design_ic_visibility.xml": {
- "Size": 540
+ "res/color-v21/abc_btn_colored_borderless_text_material.xml": {
+ "Size": 464
},
- "res/drawable-hdpi-v4/abc_ab_share_pack_mtrl_alpha.9.png": {
- "Size": 272
+ "res/color-v23/abc_btn_colored_borderless_text_material.xml": {
+ "Size": 500
},
- "res/drawable-hdpi-v4/abc_btn_check_to_on_mtrl_000.png": {
- "Size": 227
+ "res/color-v23/abc_btn_colored_text_material.xml": {
+ "Size": 500
},
- "res/drawable-hdpi-v4/abc_btn_check_to_on_mtrl_015.png": {
- "Size": 404
+ "res/color-v23/abc_color_highlight_material.xml": {
+ "Size": 544
},
- "res/drawable-hdpi-v4/abc_btn_radio_to_on_mtrl_000.png": {
- "Size": 464
+ "res/color-v23/abc_tint_btn_checkable.xml": {
+ "Size": 624
},
- "res/drawable-hdpi-v4/abc_btn_radio_to_on_mtrl_015.png": {
- "Size": 563
+ "res/color-v23/abc_tint_default.xml": {
+ "Size": 1120
},
- "res/drawable-hdpi-v4/abc_btn_switch_to_on_mtrl_00001.9.png": {
- "Size": 1096
+ "res/color-v23/abc_tint_edittext.xml": {
+ "Size": 668
},
- "res/drawable-hdpi-v4/abc_btn_switch_to_on_mtrl_00012.9.png": {
- "Size": 1243
+ "res/color-v23/abc_tint_seek_thumb.xml": {
+ "Size": 500
},
- "res/drawable-hdpi-v4/abc_cab_background_top_mtrl_alpha.9.png": {
- "Size": 226
+ "res/color-v23/abc_tint_spinner.xml": {
+ "Size": 668
},
- "res/drawable-hdpi-v4/abc_ic_commit_search_api_mtrl_alpha.png": {
- "Size": 171
+ "res/color-v23/abc_tint_switch_track.xml": {
+ "Size": 664
},
- "res/drawable-hdpi-v4/abc_ic_menu_copy_mtrl_am_alpha.png": {
- "Size": 202
+ "res/color-v23/design_tint_password_toggle.xml": {
+ "Size": 376
},
- "res/drawable-hdpi-v4/abc_ic_menu_cut_mtrl_alpha.png": {
- "Size": 404
+ "res/drawable/abc_btn_borderless_material.xml": {
+ "Size": 588
},
- "res/drawable-hdpi-v4/abc_ic_menu_paste_mtrl_am_alpha.png": {
- "Size": 226
+ "res/drawable/abc_btn_check_material.xml": {
+ "Size": 464
},
- "res/drawable-hdpi-v4/abc_ic_menu_selectall_mtrl_alpha.png": {
- "Size": 215
+ "res/drawable/abc_btn_check_material_anim.xml": {
+ "Size": 816
},
- "res/drawable-hdpi-v4/abc_ic_menu_share_mtrl_alpha.png": {
- "Size": 389
+ "res/drawable/abc_btn_colored_material.xml": {
+ "Size": 344
},
- "res/drawable-hdpi-v4/abc_ic_star_black_16dp.png": {
- "Size": 263
+ "res/drawable/abc_btn_default_mtrl_shape.xml": {
+ "Size": 932
},
- "res/drawable-hdpi-v4/abc_ic_star_black_36dp.png": {
- "Size": 522
+ "res/drawable/abc_btn_radio_material.xml": {
+ "Size": 464
},
- "res/drawable-hdpi-v4/abc_ic_star_black_48dp.png": {
- "Size": 668
+ "res/drawable/abc_btn_radio_material_anim.xml": {
+ "Size": 816
},
- "res/drawable-hdpi-v4/abc_ic_star_half_black_16dp.png": {
- "Size": 197
+ "res/drawable/abc_cab_background_internal_bg.xml": {
+ "Size": 372
},
- "res/drawable-hdpi-v4/abc_ic_star_half_black_36dp.png": {
- "Size": 328
+ "res/drawable/abc_cab_background_top_material.xml": {
+ "Size": 336
},
- "res/drawable-hdpi-v4/abc_ic_star_half_black_48dp.png": {
- "Size": 431
+ "res/drawable/abc_dialog_material_background.xml": {
+ "Size": 716
},
- "res/drawable-hdpi-v4/abc_list_divider_mtrl_alpha.9.png": {
- "Size": 167
+ "res/drawable/abc_edit_text_material.xml": {
+ "Size": 868
},
- "res/drawable-hdpi-v4/abc_list_focused_holo.9.png": {
- "Size": 244
+ "res/drawable/abc_ic_ab_back_material.xml": {
+ "Size": 692
},
- "res/drawable-hdpi-v4/abc_list_longpressed_holo.9.png": {
- "Size": 212
+ "res/drawable/abc_ic_arrow_drop_right_black_24dp.xml": {
+ "Size": 1000
},
- "res/drawable-hdpi-v4/abc_list_pressed_holo_dark.9.png": {
- "Size": 208
+ "res/drawable/abc_ic_clear_material.xml": {
+ "Size": 684
},
- "res/drawable-hdpi-v4/abc_list_pressed_holo_light.9.png": {
- "Size": 208
+ "res/drawable/abc_ic_go_search_api_material.xml": {
+ "Size": 640
},
- "res/drawable-hdpi-v4/abc_list_selector_disabled_holo_dark.9.png": {
- "Size": 228
+ "res/drawable/abc_ic_menu_overflow_material.xml": {
+ "Size": 792
},
- "res/drawable-hdpi-v4/abc_list_selector_disabled_holo_light.9.png": {
- "Size": 229
+ "res/drawable/abc_ic_search_api_material.xml": {
+ "Size": 812
},
- "res/drawable-hdpi-v4/abc_menu_hardkey_panel_mtrl_mult.9.png": {
- "Size": 738
+ "res/drawable/abc_ic_voice_search_api_material.xml": {
+ "Size": 828
},
- "res/drawable-hdpi-v4/abc_popup_background_mtrl_mult.9.png": {
- "Size": 1098
+ "res/drawable/abc_item_background_holo_dark.xml": {
+ "Size": 1012
},
- "res/drawable-hdpi-v4/abc_scrubber_control_off_mtrl_alpha.png": {
- "Size": 201
+ "res/drawable/abc_item_background_holo_light.xml": {
+ "Size": 1012
},
- "res/drawable-hdpi-v4/abc_scrubber_control_to_pressed_mtrl_000.png": {
- "Size": 196
+ "res/drawable/abc_list_divider_material.xml": {
+ "Size": 480
},
- "res/drawable-hdpi-v4/abc_scrubber_control_to_pressed_mtrl_005.png": {
- "Size": 272
+ "res/drawable/abc_list_selector_background_transition_holo_dark.xml": {
+ "Size": 424
},
- "res/drawable-hdpi-v4/abc_scrubber_primary_mtrl_alpha.9.png": {
- "Size": 205
+ "res/drawable/abc_list_selector_background_transition_holo_light.xml": {
+ "Size": 424
},
- "res/drawable-hdpi-v4/abc_scrubber_track_mtrl_alpha.9.png": {
- "Size": 196
+ "res/drawable/abc_list_selector_holo_dark.xml": {
+ "Size": 1064
},
- "res/drawable-hdpi-v4/abc_spinner_mtrl_am_alpha.9.png": {
- "Size": 345
+ "res/drawable/abc_list_selector_holo_light.xml": {
+ "Size": 1064
},
- "res/drawable-hdpi-v4/abc_switch_track_mtrl_alpha.9.png": {
- "Size": 484
+ "res/drawable/abc_ratingbar_indicator_material.xml": {
+ "Size": 664
},
- "res/drawable-hdpi-v4/abc_tab_indicator_mtrl_alpha.9.png": {
- "Size": 190
+ "res/drawable/abc_ratingbar_material.xml": {
+ "Size": 664
},
- "res/drawable-hdpi-v4/abc_text_select_handle_left_mtrl_dark.png": {
- "Size": 278
+ "res/drawable/abc_ratingbar_small_material.xml": {
+ "Size": 664
},
- "res/drawable-hdpi-v4/abc_text_select_handle_left_mtrl_light.png": {
- "Size": 278
+ "res/drawable/abc_seekbar_thumb_material.xml": {
+ "Size": 1100
},
- "res/drawable-hdpi-v4/abc_text_select_handle_middle_mtrl_dark.png": {
- "Size": 398
+ "res/drawable/abc_seekbar_tick_mark_material.xml": {
+ "Size": 516
},
- "res/drawable-hdpi-v4/abc_text_select_handle_middle_mtrl_light.png": {
- "Size": 396
+ "res/drawable/abc_seekbar_track_material.xml": {
+ "Size": 1408
},
- "res/drawable-hdpi-v4/abc_text_select_handle_right_mtrl_dark.png": {
- "Size": 263
+ "res/drawable/abc_spinner_textfield_background_material.xml": {
+ "Size": 1160
},
- "res/drawable-hdpi-v4/abc_text_select_handle_right_mtrl_light.png": {
- "Size": 262
+ "res/drawable/abc_switch_thumb_material.xml": {
+ "Size": 464
},
- "res/drawable-hdpi-v4/abc_textfield_activated_mtrl_alpha.9.png": {
- "Size": 186
+ "res/drawable/abc_tab_indicator_material.xml": {
+ "Size": 468
},
- "res/drawable-hdpi-v4/abc_textfield_default_mtrl_alpha.9.png": {
- "Size": 192
+ "res/drawable/abc_text_cursor_material.xml": {
+ "Size": 516
},
- "res/drawable-hdpi-v4/abc_textfield_search_activated_mtrl_alpha.9.png": {
- "Size": 178
+ "res/drawable/abc_textfield_search_material.xml": {
+ "Size": 756
},
- "res/drawable-hdpi-v4/abc_textfield_search_default_mtrl_alpha.9.png": {
+ "res/drawable/abc_vector_test.xml": {
+ "Size": 612
+ },
+ "res/drawable/btn_checkbox_checked_mtrl.xml": {
+ "Size": 2688
+ },
+ "res/drawable/btn_checkbox_checked_to_unchecked_mtrl_animation.xml": {
+ "Size": 688
+ },
+ "res/drawable/btn_checkbox_unchecked_mtrl.xml": {
+ "Size": 2660
+ },
+ "res/drawable/btn_checkbox_unchecked_to_checked_mtrl_animation.xml": {
+ "Size": 688
+ },
+ "res/drawable/btn_radio_off_mtrl.xml": {
+ "Size": 1728
+ },
+ "res/drawable/btn_radio_off_to_on_mtrl_animation.xml": {
+ "Size": 680
+ },
+ "res/drawable/btn_radio_on_mtrl.xml": {
+ "Size": 1656
+ },
+ "res/drawable/btn_radio_on_to_off_mtrl_animation.xml": {
+ "Size": 680
+ },
+ "res/drawable/design_bottom_navigation_item_background.xml": {
+ "Size": 784
+ },
+ "res/drawable/design_fab_background.xml": {
+ "Size": 372
+ },
+ "res/drawable/design_password_eye.xml": {
+ "Size": 464
+ },
+ "res/drawable/design_snackbar_background.xml": {
+ "Size": 484
+ },
+ "res/drawable/ic_mtrl_chip_checked_black.xml": {
+ "Size": 600
+ },
+ "res/drawable/ic_mtrl_chip_checked_circle.xml": {
+ "Size": 940
+ },
+ "res/drawable/ic_mtrl_chip_close_circle.xml": {
+ "Size": 808
+ },
+ "res/drawable/mtrl_snackbar_background.xml": {
+ "Size": 484
+ },
+ "res/drawable/mtrl_tabs_default_indicator.xml": {
+ "Size": 628
+ },
+ "res/drawable/navigation_empty_icon.xml": {
+ "Size": 516
+ },
+ "res/drawable/notification_bg.xml": {
+ "Size": 532
+ },
+ "res/drawable/notification_bg_low.xml": {
+ "Size": 532
+ },
+ "res/drawable/notification_icon_background.xml": {
+ "Size": 372
+ },
+ "res/drawable/notification_tile_bg.xml": {
+ "Size": 304
+ },
+ "res/drawable/tooltip_frame_dark.xml": {
+ "Size": 484
+ },
+ "res/drawable/tooltip_frame_light.xml": {
+ "Size": 484
+ },
+ "res/drawable-anydpi-v21/design_ic_visibility.xml": {
+ "Size": 540
+ },
+ "res/drawable-anydpi-v21/design_ic_visibility_off.xml": {
+ "Size": 1144
+ },
+ "res/drawable-hdpi-v4/abc_ab_share_pack_mtrl_alpha.9.png": {
+ "Size": 272
+ },
+ "res/drawable-hdpi-v4/abc_btn_check_to_on_mtrl_000.png": {
+ "Size": 227
+ },
+ "res/drawable-hdpi-v4/abc_btn_check_to_on_mtrl_015.png": {
+ "Size": 404
+ },
+ "res/drawable-hdpi-v4/abc_btn_radio_to_on_mtrl_000.png": {
+ "Size": 464
+ },
+ "res/drawable-hdpi-v4/abc_btn_radio_to_on_mtrl_015.png": {
+ "Size": 563
+ },
+ "res/drawable-hdpi-v4/abc_btn_switch_to_on_mtrl_00001.9.png": {
+ "Size": 1096
+ },
+ "res/drawable-hdpi-v4/abc_btn_switch_to_on_mtrl_00012.9.png": {
+ "Size": 1243
+ },
+ "res/drawable-hdpi-v4/abc_cab_background_top_mtrl_alpha.9.png": {
+ "Size": 226
+ },
+ "res/drawable-hdpi-v4/abc_ic_commit_search_api_mtrl_alpha.png": {
+ "Size": 171
+ },
+ "res/drawable-hdpi-v4/abc_ic_menu_copy_mtrl_am_alpha.png": {
+ "Size": 202
+ },
+ "res/drawable-hdpi-v4/abc_ic_menu_cut_mtrl_alpha.png": {
+ "Size": 404
+ },
+ "res/drawable-hdpi-v4/abc_ic_menu_paste_mtrl_am_alpha.png": {
+ "Size": 226
+ },
+ "res/drawable-hdpi-v4/abc_ic_menu_selectall_mtrl_alpha.png": {
+ "Size": 215
+ },
+ "res/drawable-hdpi-v4/abc_ic_menu_share_mtrl_alpha.png": {
+ "Size": 389
+ },
+ "res/drawable-hdpi-v4/abc_ic_star_black_16dp.png": {
+ "Size": 263
+ },
+ "res/drawable-hdpi-v4/abc_ic_star_black_36dp.png": {
+ "Size": 522
+ },
+ "res/drawable-hdpi-v4/abc_ic_star_black_48dp.png": {
+ "Size": 668
+ },
+ "res/drawable-hdpi-v4/abc_ic_star_half_black_16dp.png": {
+ "Size": 197
+ },
+ "res/drawable-hdpi-v4/abc_ic_star_half_black_36dp.png": {
+ "Size": 328
+ },
+ "res/drawable-hdpi-v4/abc_ic_star_half_black_48dp.png": {
+ "Size": 431
+ },
+ "res/drawable-hdpi-v4/abc_list_divider_mtrl_alpha.9.png": {
+ "Size": 167
+ },
+ "res/drawable-hdpi-v4/abc_list_focused_holo.9.png": {
+ "Size": 244
+ },
+ "res/drawable-hdpi-v4/abc_list_longpressed_holo.9.png": {
+ "Size": 212
+ },
+ "res/drawable-hdpi-v4/abc_list_pressed_holo_dark.9.png": {
+ "Size": 208
+ },
+ "res/drawable-hdpi-v4/abc_list_pressed_holo_light.9.png": {
+ "Size": 208
+ },
+ "res/drawable-hdpi-v4/abc_list_selector_disabled_holo_dark.9.png": {
+ "Size": 228
+ },
+ "res/drawable-hdpi-v4/abc_list_selector_disabled_holo_light.9.png": {
+ "Size": 229
+ },
+ "res/drawable-hdpi-v4/abc_menu_hardkey_panel_mtrl_mult.9.png": {
+ "Size": 738
+ },
+ "res/drawable-hdpi-v4/abc_popup_background_mtrl_mult.9.png": {
+ "Size": 1098
+ },
+ "res/drawable-hdpi-v4/abc_scrubber_control_off_mtrl_alpha.png": {
+ "Size": 201
+ },
+ "res/drawable-hdpi-v4/abc_scrubber_control_to_pressed_mtrl_000.png": {
+ "Size": 196
+ },
+ "res/drawable-hdpi-v4/abc_scrubber_control_to_pressed_mtrl_005.png": {
+ "Size": 272
+ },
+ "res/drawable-hdpi-v4/abc_scrubber_primary_mtrl_alpha.9.png": {
+ "Size": 205
+ },
+ "res/drawable-hdpi-v4/abc_scrubber_track_mtrl_alpha.9.png": {
+ "Size": 196
+ },
+ "res/drawable-hdpi-v4/abc_spinner_mtrl_am_alpha.9.png": {
+ "Size": 345
+ },
+ "res/drawable-hdpi-v4/abc_switch_track_mtrl_alpha.9.png": {
+ "Size": 484
+ },
+ "res/drawable-hdpi-v4/abc_tab_indicator_mtrl_alpha.9.png": {
+ "Size": 190
+ },
+ "res/drawable-hdpi-v4/abc_text_select_handle_left_mtrl_dark.png": {
+ "Size": 278
+ },
+ "res/drawable-hdpi-v4/abc_text_select_handle_left_mtrl_light.png": {
+ "Size": 278
+ },
+ "res/drawable-hdpi-v4/abc_text_select_handle_middle_mtrl_dark.png": {
+ "Size": 398
+ },
+ "res/drawable-hdpi-v4/abc_text_select_handle_middle_mtrl_light.png": {
+ "Size": 396
+ },
+ "res/drawable-hdpi-v4/abc_text_select_handle_right_mtrl_dark.png": {
+ "Size": 263
+ },
+ "res/drawable-hdpi-v4/abc_text_select_handle_right_mtrl_light.png": {
+ "Size": 262
+ },
+ "res/drawable-hdpi-v4/abc_textfield_activated_mtrl_alpha.9.png": {
+ "Size": 186
+ },
+ "res/drawable-hdpi-v4/abc_textfield_default_mtrl_alpha.9.png": {
+ "Size": 192
+ },
+ "res/drawable-hdpi-v4/abc_textfield_search_activated_mtrl_alpha.9.png": {
"Size": 178
},
- "res/drawable-hdpi-v4/design_ic_visibility_off.png": {
- "Size": 507
+ "res/drawable-hdpi-v4/abc_textfield_search_default_mtrl_alpha.9.png": {
+ "Size": 178
},
"res/drawable-hdpi-v4/design_ic_visibility.png": {
"Size": 470
},
+ "res/drawable-hdpi-v4/design_ic_visibility_off.png": {
+ "Size": 507
+ },
"res/drawable-hdpi-v4/icon.png": {
"Size": 4762
},
@@ -706,12 +889,12 @@
"res/drawable-hdpi-v4/notification_bg_low_pressed.9.png": {
"Size": 225
},
- "res/drawable-hdpi-v4/notification_bg_normal_pressed.9.png": {
- "Size": 225
- },
"res/drawable-hdpi-v4/notification_bg_normal.9.png": {
"Size": 212
},
+ "res/drawable-hdpi-v4/notification_bg_normal_pressed.9.png": {
+ "Size": 225
+ },
"res/drawable-hdpi-v4/notify_panel_notification_icon_bg.png": {
"Size": 107
},
@@ -901,12 +1084,12 @@
"res/drawable-mdpi-v4/abc_textfield_search_default_mtrl_alpha.9.png": {
"Size": 178
},
- "res/drawable-mdpi-v4/design_ic_visibility_off.png": {
- "Size": 351
- },
"res/drawable-mdpi-v4/design_ic_visibility.png": {
"Size": 309
},
+ "res/drawable-mdpi-v4/design_ic_visibility_off.png": {
+ "Size": 351
+ },
"res/drawable-mdpi-v4/icon.png": {
"Size": 2200
},
@@ -916,12 +1099,12 @@
"res/drawable-mdpi-v4/notification_bg_low_pressed.9.png": {
"Size": 223
},
- "res/drawable-mdpi-v4/notification_bg_normal_pressed.9.png": {
- "Size": 223
- },
"res/drawable-mdpi-v4/notification_bg_normal.9.png": {
"Size": 215
},
+ "res/drawable-mdpi-v4/notification_bg_normal_pressed.9.png": {
+ "Size": 223
+ },
"res/drawable-mdpi-v4/notify_panel_notification_icon_bg.png": {
"Size": 98
},
@@ -1129,12 +1312,12 @@
"res/drawable-xhdpi-v4/abc_textfield_search_default_mtrl_alpha.9.png": {
"Size": 182
},
- "res/drawable-xhdpi-v4/design_ic_visibility_off.png": {
- "Size": 629
- },
"res/drawable-xhdpi-v4/design_ic_visibility.png": {
"Size": 593
},
+ "res/drawable-xhdpi-v4/design_ic_visibility_off.png": {
+ "Size": 629
+ },
"res/drawable-xhdpi-v4/icon.png": {
"Size": 7462
},
@@ -1144,12 +1327,12 @@
"res/drawable-xhdpi-v4/notification_bg_low_pressed.9.png": {
"Size": 252
},
- "res/drawable-xhdpi-v4/notification_bg_normal_pressed.9.png": {
- "Size": 247
- },
"res/drawable-xhdpi-v4/notification_bg_normal.9.png": {
"Size": 221
},
+ "res/drawable-xhdpi-v4/notification_bg_normal_pressed.9.png": {
+ "Size": 247
+ },
"res/drawable-xhdpi-v4/notify_panel_notification_icon_bg.png": {
"Size": 138
},
@@ -1294,12 +1477,12 @@
"res/drawable-xxhdpi-v4/abc_textfield_search_default_mtrl_alpha.9.png": {
"Size": 186
},
- "res/drawable-xxhdpi-v4/design_ic_visibility_off.png": {
- "Size": 884
- },
"res/drawable-xxhdpi-v4/design_ic_visibility.png": {
"Size": 868
},
+ "res/drawable-xxhdpi-v4/design_ic_visibility_off.png": {
+ "Size": 884
+ },
"res/drawable-xxhdpi-v4/icon.png": {
"Size": 13092
},
@@ -1381,207 +1564,15 @@
"res/drawable-xxxhdpi-v4/abc_text_select_handle_right_mtrl_light.png": {
"Size": 513
},
- "res/drawable-xxxhdpi-v4/design_ic_visibility_off.png": {
- "Size": 1201
- },
"res/drawable-xxxhdpi-v4/design_ic_visibility.png": {
"Size": 1155
},
+ "res/drawable-xxxhdpi-v4/design_ic_visibility_off.png": {
+ "Size": 1201
+ },
"res/drawable-xxxhdpi-v4/icon.png": {
"Size": 20118
},
- "res/drawable/abc_btn_borderless_material.xml": {
- "Size": 588
- },
- "res/drawable/abc_btn_check_material_anim.xml": {
- "Size": 816
- },
- "res/drawable/abc_btn_check_material.xml": {
- "Size": 464
- },
- "res/drawable/abc_btn_colored_material.xml": {
- "Size": 344
- },
- "res/drawable/abc_btn_default_mtrl_shape.xml": {
- "Size": 932
- },
- "res/drawable/abc_btn_radio_material_anim.xml": {
- "Size": 816
- },
- "res/drawable/abc_btn_radio_material.xml": {
- "Size": 464
- },
- "res/drawable/abc_cab_background_internal_bg.xml": {
- "Size": 372
- },
- "res/drawable/abc_cab_background_top_material.xml": {
- "Size": 336
- },
- "res/drawable/abc_dialog_material_background.xml": {
- "Size": 716
- },
- "res/drawable/abc_edit_text_material.xml": {
- "Size": 868
- },
- "res/drawable/abc_ic_ab_back_material.xml": {
- "Size": 692
- },
- "res/drawable/abc_ic_arrow_drop_right_black_24dp.xml": {
- "Size": 1000
- },
- "res/drawable/abc_ic_clear_material.xml": {
- "Size": 684
- },
- "res/drawable/abc_ic_go_search_api_material.xml": {
- "Size": 640
- },
- "res/drawable/abc_ic_menu_overflow_material.xml": {
- "Size": 792
- },
- "res/drawable/abc_ic_search_api_material.xml": {
- "Size": 812
- },
- "res/drawable/abc_ic_voice_search_api_material.xml": {
- "Size": 828
- },
- "res/drawable/abc_item_background_holo_dark.xml": {
- "Size": 1012
- },
- "res/drawable/abc_item_background_holo_light.xml": {
- "Size": 1012
- },
- "res/drawable/abc_list_divider_material.xml": {
- "Size": 480
- },
- "res/drawable/abc_list_selector_background_transition_holo_dark.xml": {
- "Size": 424
- },
- "res/drawable/abc_list_selector_background_transition_holo_light.xml": {
- "Size": 424
- },
- "res/drawable/abc_list_selector_holo_dark.xml": {
- "Size": 1064
- },
- "res/drawable/abc_list_selector_holo_light.xml": {
- "Size": 1064
- },
- "res/drawable/abc_ratingbar_indicator_material.xml": {
- "Size": 664
- },
- "res/drawable/abc_ratingbar_material.xml": {
- "Size": 664
- },
- "res/drawable/abc_ratingbar_small_material.xml": {
- "Size": 664
- },
- "res/drawable/abc_seekbar_thumb_material.xml": {
- "Size": 1100
- },
- "res/drawable/abc_seekbar_tick_mark_material.xml": {
- "Size": 516
- },
- "res/drawable/abc_seekbar_track_material.xml": {
- "Size": 1408
- },
- "res/drawable/abc_spinner_textfield_background_material.xml": {
- "Size": 1160
- },
- "res/drawable/abc_switch_thumb_material.xml": {
- "Size": 464
- },
- "res/drawable/abc_tab_indicator_material.xml": {
- "Size": 468
- },
- "res/drawable/abc_text_cursor_material.xml": {
- "Size": 516
- },
- "res/drawable/abc_textfield_search_material.xml": {
- "Size": 756
- },
- "res/drawable/abc_vector_test.xml": {
- "Size": 612
- },
- "res/drawable/btn_checkbox_checked_mtrl.xml": {
- "Size": 2688
- },
- "res/drawable/btn_checkbox_checked_to_unchecked_mtrl_animation.xml": {
- "Size": 688
- },
- "res/drawable/btn_checkbox_unchecked_mtrl.xml": {
- "Size": 2660
- },
- "res/drawable/btn_checkbox_unchecked_to_checked_mtrl_animation.xml": {
- "Size": 688
- },
- "res/drawable/btn_radio_off_mtrl.xml": {
- "Size": 1728
- },
- "res/drawable/btn_radio_off_to_on_mtrl_animation.xml": {
- "Size": 680
- },
- "res/drawable/btn_radio_on_mtrl.xml": {
- "Size": 1656
- },
- "res/drawable/btn_radio_on_to_off_mtrl_animation.xml": {
- "Size": 680
- },
- "res/drawable/design_bottom_navigation_item_background.xml": {
- "Size": 784
- },
- "res/drawable/design_fab_background.xml": {
- "Size": 372
- },
- "res/drawable/design_password_eye.xml": {
- "Size": 464
- },
- "res/drawable/design_snackbar_background.xml": {
- "Size": 484
- },
- "res/drawable/ic_mtrl_chip_checked_black.xml": {
- "Size": 600
- },
- "res/drawable/ic_mtrl_chip_checked_circle.xml": {
- "Size": 940
- },
- "res/drawable/ic_mtrl_chip_close_circle.xml": {
- "Size": 808
- },
- "res/drawable/mtrl_snackbar_background.xml": {
- "Size": 484
- },
- "res/drawable/mtrl_tabs_default_indicator.xml": {
- "Size": 628
- },
- "res/drawable/navigation_empty_icon.xml": {
- "Size": 516
- },
- "res/drawable/notification_bg_low.xml": {
- "Size": 532
- },
- "res/drawable/notification_bg.xml": {
- "Size": 532
- },
- "res/drawable/notification_icon_background.xml": {
- "Size": 372
- },
- "res/drawable/notification_tile_bg.xml": {
- "Size": 304
- },
- "res/drawable/tooltip_frame_dark.xml": {
- "Size": 484
- },
- "res/drawable/tooltip_frame_light.xml": {
- "Size": 484
- },
- "res/interpolator-v21/mtrl_fast_out_linear_in.xml": {
- "Size": 400
- },
- "res/interpolator-v21/mtrl_fast_out_slow_in.xml": {
- "Size": 400
- },
- "res/interpolator-v21/mtrl_linear_out_slow_in.xml": {
- "Size": 400
- },
"res/interpolator/btn_checkbox_checked_mtrl_animation_interpolator_0.xml": {
"Size": 316
},
@@ -1609,53 +1600,20 @@
"res/interpolator/mtrl_fast_out_slow_in.xml": {
"Size": 144
},
- "res/interpolator/mtrl_linear_out_slow_in.xml": {
- "Size": 136
- },
"res/interpolator/mtrl_linear.xml": {
"Size": 132
},
- "res/layout-sw600dp-v13/design_layout_snackbar.xml": {
- "Size": 528
- },
- "res/layout-sw600dp-v13/mtrl_layout_snackbar.xml": {
- "Size": 528
- },
- "res/layout-v16/notification_template_custom_big.xml": {
- "Size": 3208
- },
- "res/layout-v21/abc_screen_toolbar.xml": {
- "Size": 1504
- },
- "res/layout-v21/fallbacktoolbardonotuse.xml": {
- "Size": 496
- },
- "res/layout-v21/notification_action_tombstone.xml": {
- "Size": 1228
- },
- "res/layout-v21/notification_action.xml": {
- "Size": 1052
- },
- "res/layout-v21/notification_template_custom_big.xml": {
- "Size": 2456
- },
- "res/layout-v21/notification_template_icon_group.xml": {
- "Size": 988
- },
- "res/layout-v21/toolbar.xml": {
- "Size": 496
- },
- "res/layout-v22/abc_alert_dialog_button_bar_material.xml": {
- "Size": 1584
+ "res/interpolator/mtrl_linear_out_slow_in.xml": {
+ "Size": 136
},
- "res/layout-v26/abc_screen_toolbar.xml": {
- "Size": 1560
+ "res/interpolator-v21/mtrl_fast_out_linear_in.xml": {
+ "Size": 400
},
- "res/layout-watch-v20/abc_alert_dialog_button_bar_material.xml": {
- "Size": 1208
+ "res/interpolator-v21/mtrl_fast_out_slow_in.xml": {
+ "Size": 400
},
- "res/layout-watch-v20/abc_alert_dialog_title_material.xml": {
- "Size": 1352
+ "res/interpolator-v21/mtrl_linear_out_slow_in.xml": {
+ "Size": 400
},
"res/layout/abc_action_bar_title_item.xml": {
"Size": 872
@@ -1675,12 +1633,12 @@
"res/layout/abc_action_mode_close_item_material.xml": {
"Size": 840
},
- "res/layout/abc_activity_chooser_view_list_item.xml": {
- "Size": 1304
- },
"res/layout/abc_activity_chooser_view.xml": {
"Size": 1684
},
+ "res/layout/abc_activity_chooser_view_list_item.xml": {
+ "Size": 1304
+ },
"res/layout/abc_alert_dialog_button_bar_material.xml": {
"Size": 1536
},
@@ -1720,12 +1678,12 @@
"res/layout/abc_screen_content_include.xml": {
"Size": 548
},
- "res/layout/abc_screen_simple_overlay_action_mode.xml": {
- "Size": 792
- },
"res/layout/abc_screen_simple.xml": {
"Size": 832
},
+ "res/layout/abc_screen_simple_overlay_action_mode.xml": {
+ "Size": 792
+ },
"res/layout/abc_screen_toolbar.xml": {
"Size": 1452
},
@@ -1759,12 +1717,12 @@
"res/layout/design_bottom_sheet_dialog.xml": {
"Size": 1184
},
- "res/layout/design_layout_snackbar_include.xml": {
- "Size": 1444
- },
"res/layout/design_layout_snackbar.xml": {
"Size": 528
},
+ "res/layout/design_layout_snackbar_include.xml": {
+ "Size": 1444
+ },
"res/layout/design_layout_tab_icon.xml": {
"Size": 408
},
@@ -1774,6 +1732,9 @@
"res/layout/design_menu_item_action_area.xml": {
"Size": 320
},
+ "res/layout/design_navigation_item.xml": {
+ "Size": 536
+ },
"res/layout/design_navigation_item_header.xml": {
"Size": 440
},
@@ -1783,15 +1744,12 @@
"res/layout/design_navigation_item_subheader.xml": {
"Size": 564
},
- "res/layout/design_navigation_item.xml": {
- "Size": 536
+ "res/layout/design_navigation_menu.xml": {
+ "Size": 528
},
"res/layout/design_navigation_menu_item.xml": {
"Size": 856
},
- "res/layout/design_navigation_menu.xml": {
- "Size": 528
- },
"res/layout/design_text_input_password_icon.xml": {
"Size": 564
},
@@ -1807,35 +1765,35 @@
"res/layout/main.xml": {
"Size": 544
},
- "res/layout/mtrl_layout_snackbar_include.xml": {
- "Size": 1404
- },
"res/layout/mtrl_layout_snackbar.xml": {
"Size": 528
},
- "res/layout/notification_action_tombstone.xml": {
- "Size": 1332
+ "res/layout/mtrl_layout_snackbar_include.xml": {
+ "Size": 1404
},
"res/layout/notification_action.xml": {
"Size": 1156
},
+ "res/layout/notification_action_tombstone.xml": {
+ "Size": 1332
+ },
"res/layout/notification_media_action.xml": {
"Size": 564
},
"res/layout/notification_media_cancel_action.xml": {
"Size": 744
},
+ "res/layout/notification_template_big_media.xml": {
+ "Size": 1696
+ },
"res/layout/notification_template_big_media_custom.xml": {
"Size": 3044
},
- "res/layout/notification_template_big_media_narrow_custom.xml": {
- "Size": 3216
- },
"res/layout/notification_template_big_media_narrow.xml": {
"Size": 1824
},
- "res/layout/notification_template_big_media.xml": {
- "Size": 1696
+ "res/layout/notification_template_big_media_narrow_custom.xml": {
+ "Size": 3216
},
"res/layout/notification_template_icon_group.xml": {
"Size": 392
@@ -1843,12 +1801,12 @@
"res/layout/notification_template_lines_media.xml": {
"Size": 2872
},
- "res/layout/notification_template_media_custom.xml": {
- "Size": 2756
- },
"res/layout/notification_template_media.xml": {
"Size": 1292
},
+ "res/layout/notification_template_media_custom.xml": {
+ "Size": 2756
+ },
"res/layout/notification_template_part_chronometer.xml": {
"Size": 440
},
@@ -1879,6 +1837,48 @@
"res/layout/toolbar.xml": {
"Size": 452
},
+ "res/layout-sw600dp-v13/design_layout_snackbar.xml": {
+ "Size": 528
+ },
+ "res/layout-sw600dp-v13/mtrl_layout_snackbar.xml": {
+ "Size": 528
+ },
+ "res/layout-v16/notification_template_custom_big.xml": {
+ "Size": 3208
+ },
+ "res/layout-v21/abc_screen_toolbar.xml": {
+ "Size": 1504
+ },
+ "res/layout-v21/fallbacktoolbardonotuse.xml": {
+ "Size": 496
+ },
+ "res/layout-v21/notification_action.xml": {
+ "Size": 1052
+ },
+ "res/layout-v21/notification_action_tombstone.xml": {
+ "Size": 1228
+ },
+ "res/layout-v21/notification_template_custom_big.xml": {
+ "Size": 2456
+ },
+ "res/layout-v21/notification_template_icon_group.xml": {
+ "Size": 988
+ },
+ "res/layout-v21/toolbar.xml": {
+ "Size": 496
+ },
+ "res/layout-v22/abc_alert_dialog_button_bar_material.xml": {
+ "Size": 1584
+ },
+ "res/layout-v26/abc_screen_toolbar.xml": {
+ "Size": 1560
+ },
+ "res/layout-watch-v20/abc_alert_dialog_button_bar_material.xml": {
+ "Size": 1208
+ },
+ "res/layout-watch-v20/abc_alert_dialog_title_material.xml": {
+ "Size": 1352
+ },
"resources.arsc": {
"Size": 341040
}
diff --git a/tests/Mono.Android-Tests/Mono.Android-Test.Shared.projitems b/tests/Mono.Android-Tests/Mono.Android-Test.Shared.projitems
index f0f471e85b4..9881054e160 100644
--- a/tests/Mono.Android-Tests/Mono.Android-Test.Shared.projitems
+++ b/tests/Mono.Android-Tests/Mono.Android-Test.Shared.projitems
@@ -47,6 +47,7 @@
+
diff --git a/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidClientHandlerTests.cs b/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidClientHandlerTests.cs
index f6b344744c4..361adc860eb 100644
--- a/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidClientHandlerTests.cs
+++ b/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidClientHandlerTests.cs
@@ -283,76 +283,67 @@ public void Redirect_POST_With_Content_Works ()
Assert.AreEqual (redirectedURI, response.RequestMessage.RequestUri, "Invalid redirected URI");
}
}
+ }
- [TestFixture]
- public class AndroidClientHandlerTests : AndroidHandlerTestBase
+ [TestFixture]
+ public class AndroidClientHandlerTests : AndroidHandlerTestBase
+ {
+ protected override HttpMessageHandler CreateHandler ()
{
- protected override HttpMessageHandler CreateHandler ()
- {
- return new AndroidClientHandler ();
- }
-
- [Test]
- public void Properties_Defaults ()
- {
- var h = new AndroidClientHandler ();
-
- Assert.IsTrue (h.AllowAutoRedirect, "#1");
- Assert.AreEqual (DecompressionMethods.None, h.AutomaticDecompression, "#2");
- Assert.AreEqual (0, h.CookieContainer.Count, "#3");
- Assert.AreEqual (4096, h.CookieContainer.MaxCookieSize, "#3b");
- Assert.AreEqual (null, h.Credentials, "#4");
- Assert.AreEqual (50, h.MaxAutomaticRedirections, "#5");
- Assert.IsFalse (h.PreAuthenticate, "#7");
- Assert.IsNull (h.Proxy, "#8");
- Assert.IsTrue (h.SupportsAutomaticDecompression, "#9");
- Assert.IsTrue (h.SupportsProxy, "#10");
- Assert.IsTrue (h.SupportsRedirectConfiguration, "#11");
- Assert.IsTrue (h.UseCookies, "#12");
- Assert.IsFalse (h.UseDefaultCredentials, "#13");
- Assert.IsTrue (h.UseProxy, "#14");
- Assert.AreEqual (ClientCertificateOption.Manual, h.ClientCertificateOptions, "#15");
- Assert.IsNull (h.ServerCertificateCustomValidationCallback, "#16");
- }
+ return new AndroidClientHandler ();
+ }
- [Test]
- public void Properties_Invalid ()
- {
- var h = new AndroidClientHandler ();
+ [Test]
+ public void Properties_Defaults ()
+ {
+ var h = new AndroidClientHandler ();
+
+ Assert.IsTrue (h.AllowAutoRedirect, "#1");
+ Assert.AreEqual (DecompressionMethods.None, h.AutomaticDecompression, "#2");
+ Assert.AreEqual (0, h.CookieContainer.Count, "#3");
+ Assert.AreEqual (4096, h.CookieContainer.MaxCookieSize, "#3b");
+ Assert.AreEqual (null, h.Credentials, "#4");
+ Assert.AreEqual (50, h.MaxAutomaticRedirections, "#5");
+ Assert.IsFalse (h.PreAuthenticate, "#7");
+ Assert.IsNull (h.Proxy, "#8");
+ Assert.IsTrue (h.SupportsAutomaticDecompression, "#9");
+ Assert.IsTrue (h.SupportsProxy, "#10");
+ Assert.IsTrue (h.SupportsRedirectConfiguration, "#11");
+ Assert.IsTrue (h.UseCookies, "#12");
+ Assert.IsFalse (h.UseDefaultCredentials, "#13");
+ Assert.IsTrue (h.UseProxy, "#14");
+ Assert.AreEqual (ClientCertificateOption.Manual, h.ClientCertificateOptions, "#15");
+ Assert.IsNull (h.ServerCertificateCustomValidationCallback, "#16");
+ }
- try {
- h.MaxAutomaticRedirections = 0;
- Assert.Fail ("#1");
- } catch (ArgumentOutOfRangeException) {
- }
+ [Test]
+ public void Properties_Invalid ()
+ {
+ var h = new AndroidClientHandler ();
- try {
- h.MaxRequestContentBufferSize = -1;
- Assert.Fail ("#2");
- } catch (ArgumentOutOfRangeException) {
- }
+ try {
+ h.MaxAutomaticRedirections = 0;
+ Assert.Fail ("#1");
+ } catch (ArgumentOutOfRangeException) {
}
- [Test]
- public void Properties_AfterClientCreation ()
- {
- var h = new AndroidClientHandler ();
-
- h.AllowAutoRedirect = true;
-
- // We may modify properties after creating the HttpClient.
- using (var c = new HttpClient (h, true)) {
- h.AllowAutoRedirect = false;
- }
+ try {
+ h.MaxRequestContentBufferSize = -1;
+ Assert.Fail ("#2");
+ } catch (ArgumentOutOfRangeException) {
}
}
- [TestFixture]
- public class AndroidMessageHandlerTests : AndroidHandlerTestBase
+ [Test]
+ public void Properties_AfterClientCreation ()
{
- protected override HttpMessageHandler CreateHandler ()
- {
- return new AndroidMessageHandler ();
+ var h = new AndroidClientHandler ();
+
+ h.AllowAutoRedirect = true;
+
+ // We may modify properties after creating the HttpClient.
+ using (var c = new HttpClient (h, true)) {
+ h.AllowAutoRedirect = false;
}
}
}
diff --git a/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs b/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs
new file mode 100644
index 00000000000..8717dad52b9
--- /dev/null
+++ b/tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs
@@ -0,0 +1,99 @@
+using System;
+using System.Net.Http;
+using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading.Tasks;
+
+using Xamarin.Android.Net;
+
+using NUnit.Framework;
+
+namespace Xamarin.Android.NetTests
+{
+ [TestFixture]
+ public class AndroidMessageHandlerTests : AndroidHandlerTestBase
+ {
+ protected override HttpMessageHandler CreateHandler ()
+ {
+ return new AndroidMessageHandler ();
+ }
+
+ [Test]
+ public async Task ServerCertificateCustomValidationCallback_ApproveRequest ()
+ {
+ bool callbackHasBeenCalled = false;
+
+ var handler = new AndroidMessageHandler {
+ ServerCertificateCustomValidationCallback = (request, cert, chain, errors) => {
+ Assert.NotNull (request, "request");
+ Assert.AreEqual ("microsoft.com", request.RequestUri.Host);
+ Assert.NotNull (cert, "cert");
+ Assert.True (cert!.Subject.Contains ("microsoft.com"), $"Unexpected certificate subject {cert!.Subject}");
+ Assert.True (cert!.Issuer.Contains ("Microsoft"), $"Unexpected certificate issuer {cert!.Issuer}");
+ Assert.NotNull (chain, "chain");
+ Assert.AreEqual (SslPolicyErrors.None, errors);
+
+ callbackHasBeenCalled = true;
+ return true;
+ }
+ };
+
+ var client = new HttpClient (handler);
+ await client.GetStringAsync ("https://microsoft.com/");
+
+ Assert.IsTrue (callbackHasBeenCalled, "custom validation callback hasn't been called");
+ }
+
+ [Test]
+ public async Task ServerCertificateCustomValidationCallback_RejectRequest ()
+ {
+ bool callbackHasBeenCalled = false;
+ bool exceptionWasThrown = false;
+
+ var handler = new AndroidMessageHandler {
+ ServerCertificateCustomValidationCallback = (request, cert, chain, errors) => {
+ callbackHasBeenCalled = true;
+ return false;
+ }
+ };
+
+ var client = new HttpClient (handler);
+
+ try {
+ await client.GetStringAsync ("https://microsoft.com/");
+ } catch {
+ // System.Net.WebException is thrown in Debug mode
+ // Java.Security.Cert.CertificateException is thrown in Release mode
+ exceptionWasThrown = true;
+ }
+
+ Assert.IsTrue (callbackHasBeenCalled, "custom validation callback hasn't been called");
+ Assert.IsTrue (exceptionWasThrown, "validation callback hasn't rejected the request");
+ }
+
+ [Test]
+ public async Task ServerCertificateCustomValidationCallback_ApprovesRequestWithInvalidCertificate ()
+ {
+ bool callbackHasBeenCalled = false;
+ Exception? exception = null;
+
+ var handler = new AndroidMessageHandler {
+ ServerCertificateCustomValidationCallback = (request, cert, chain, errors) => {
+ callbackHasBeenCalled = true;
+ return true;
+ }
+ };
+
+ var client = new HttpClient (handler);
+
+ try {
+ await client.GetStringAsync ("https://self-signed.badssl.com/");
+ } catch (Exception e) {
+ exception = e;
+ }
+
+ Assert.IsTrue (callbackHasBeenCalled, "custom validation callback hasn't been called");
+ Assert.IsNull (exception, $"an exception was thrown: {exception}");
+ }
+ }
+}