From 58bb714f6b63cc90501ea162ad315390a8cdc7df Mon Sep 17 00:00:00 2001 From: Atsushi Eno Date: Thu, 13 Jul 2017 20:28:59 +0800 Subject: [PATCH] API compatibility fixes after enumification. It does not mean everything in this change is about enumification - actually only few changes are relevant. It is wrong attitute because it mixes different fixes, but that's what I was asked to do. Here is the list of the reported breaking changes: Perceptible = 130 230 Google changed the value! public RemoteInput.Builder SetAllowFreeFormInput (bool allowFreeFormInput allowFreeFormTextInput) The bare parameter name changes that we already resolved as "renaming to the new name is the way what we do". api-diff most likely needs fix to not report this kind of changes. public virtual void OnServiceAdded (ProfileState status, BluetoothGattService service); It is actually a bugfix: https://bugzilla.xamarin.com/show_bug.cgi?id=55473 public AdvertiseTx int TxPowerLevel { get; } It is also a bugfix for https://bugzilla.xamarin.com/show_bug.cgi?id=51293 public virtual Android.Database.ICursor Query (Android.Net.Uri url uri, string[] projection, string selection, string[] selectionArgs, string sortOrder, Android.OS.CancellationSignal cancellationSignal) public virtual void OnError (string itemId mediaId) public virtual bool EnableNetwork (int netId, bool disableOthers attemptConnect) public virtual SubscriptionInfo GetActiveSubscriptionInfoForSimSlotIndex (int slotIdx slotIndex) public virtual string GetDeviceId (int slotId slotIndex) public virtual void SetMaxEms (int maxems maxEms) public virtual void SetMaxHeight (int maxHeight maxPixels) (... and all those relevant methods on Android.Widget.TextView) public bool IsAnnotationPresent (Class annotationType annotationClass) public bool IsAssignableFrom (Class c cls) public bool IsInstance (Object object obj) public virtual bool IsAnnotationPresent (Class annotationType annotationClass) public virtual void TraceInstructions (bool enable on) public virtual void TraceMethodCalls (bool enable on) public virtual bool IsAnnotationPresent (Java.Lang.Class annotationType annotationClass) public Java.Lang.Object NewInstance (Java.Lang.Object[] args initargs) public string GetDisplayScript (Locale locale inLocale) public string GetDisplayVariant (Locale locale inLocale) public virtual int NextInt (int n bound) public CopyOnWriteArrayList (Java.Lang.Object[] array toCopyIn) (... and all those lines in Java.Util.Concurrent.CopyOnWriteArrayList) They are all parameter name fixes in Android API. MaskFlags = 4080 65520 Google changed the constant value here too. Well, it should. Java.Lang.IAutoCloseable This is a bogus report. It sure adds another interface but it does not bring in any breaking change because the derived interface XmlResourceParser also contains the only member in AutoCloseable i.e. close() ! api-check must not report this as a breaking change. This applies to all other interfaces that report the same error too. public virtual View KeyboardNavigationClusterSearch (View p0, FocusSearchDirection p1); Why is this happening? Because they are static methods that should not be part of the interface member. Why does this happen? Because this fix is not merged! https://github.com/xamarin/java.interop/pull/159 That fix really needs to be merged otherwise we keep generating these API incomatibility forever. The issue on java.time.chrono API mentioned there is actually due to totally different issue from the static <-> instance changes, so there is no excuse to not fix the static issue. public IAppendable Append (string s, int start, int end); Fixed: see src/Mono.Android/Java.Lang/StringBuffer.cs and src/Mono.Android/Java.Lang/StringBuilder.cs for details.

Removed Type Java.Lang.Reflect.Constructor.InterfaceConsts

Removed Type Java.Lang.Reflect.Method.InterfaceConsts

They must be brought be intrusive Google API changes due to the step-by-step migration from Harmony to OpenJDK. There are no members that used those consts and should be simply killed even without changes. We can take bugs IF ANYONE EVER used it. I don't waste my time on "fixing" this. public virtual bool IsAnnotationPresent (Java.Lang.Class annotationClass); public virtual void AddPropertyChangeListener (Java.Beans.IPropertyChangeListener listener); public virtual void RemovePropertyChangeListener (Java.Beans.IPropertyChangeListener listener); (in both Pack200.IPacker and Pack200.IUnpacker) public virtual bool IsDestroyed { get; } public virtual void Destroy (); They are all api-merge bug: why does api-merge preserve this method as a default interface method?? It had been non-default in earlier API Levels, therefore api-merge must generate this method as non-default. IAnnotatedElement This is new in java.lang.reflect.GenericDeclaration interface and should also be part of huge Harmony - OpenJDK migration. And unlike other new additional interfaces, those methods in AnnotatedElement are not default, so they are indeed breaking changes. At this state, I don't think there is anything we can help the situation. We cannot remove this base interface type because that will generate JCW that doesn't compile. The only idea I can think of is to completely kill this type. It's just like we give up EntityIterator. public virtual FileChannel Position (long newPosition); public virtual FileChannel Truncate (long size); public System.Threading.Tasks.Task<FileChannel> TruncateAsync (long size); This was actually newly introduced breakage for OpenJDK migration too. FileChannel now implements SeekableByteChannel, which never existed, and they require those methods to return ISeekableByteChannel in C#, not FileChannel whereas FileChannel **is** ISeekableByteChannel. So they are changed in the metadata fixup, but then this breakage. Now Position() and Truncate() are added as explicit interface implementation. However, what can we do for TruncateAsync() ? NOTHING! It is (semi-)automatically generated by `generateAsyncWrapper='true'` which is NOT defined in the interface and therefore it cannot be explicitly implemented. And it's all about return types. Javax.Security.Auth.IDestroyable This should not be reported because all those interface methods are default!

Removed Type Android.Service.Quicksettings.TileState

I explicitly removed this. It had been marked as [Obsolete]. --- .../enumification-helpers/methodmap.ext.csv | 4 +-- build-tools/scripts/BuildEverything.mk | 2 +- src/Mono.Android/Java.Lang/StringBuffer.cs | 19 +++++++++++ src/Mono.Android/Java.Lang/StringBuilder.cs | 19 +++++++++++ src/Mono.Android/Java.Nio/FileChannel.cs | 34 +++++++++++++++++++ src/Mono.Android/Mono.Android.csproj | 3 ++ src/Mono.Android/metadata | 11 +++--- src/Mono.Android/methodmap.csv | 4 +-- 8 files changed, 84 insertions(+), 12 deletions(-) create mode 100644 src/Mono.Android/Java.Lang/StringBuffer.cs create mode 100644 src/Mono.Android/Java.Lang/StringBuilder.cs create mode 100644 src/Mono.Android/Java.Nio/FileChannel.cs diff --git a/build-tools/enumification-helpers/methodmap.ext.csv b/build-tools/enumification-helpers/methodmap.ext.csv index e2dcec1fdc9..2488e8ee818 100644 --- a/build-tools/enumification-helpers/methodmap.ext.csv +++ b/build-tools/enumification-helpers/methodmap.ext.csv @@ -1675,7 +1675,8 @@ 26, android.telecom, Call.Callback, onRttInitiationFailure, reason, Android.Telecom.RttSessionModifyResult 26, android.telephony, TelephonyManager.UssdResponseCallback, onReceiveUssdResponseFailed, failureCode, Android.Telephony.UssdResultCode -26, android.icu.util, TimeZone, getTimeZone, type, Android.Icu.Util.TimeZoneType +// cannot change this at this state. +// 24, android.icu.util, TimeZone, getTimeZone, type, Android.Icu.Util.TimeZoneType 26, android.icu.util, UniversalTimeScale, bigDecimalFrom, timeScale, Android.Icu.Util.UniversalTimeScaleType 26, android.icu.util, UniversalTimeScale, from, timeScale, Android.Icu.Util.UniversalTimeScaleType 26, android.icu.util, UniversalTimeScale, getTimeScaleValue, scale, Android.Icu.Util.UniversalTimeScaleType @@ -1720,7 +1721,6 @@ 26, android.content, Intent, removeFlags, flags, Android.Content.ActivityFlags 26, android.content.pm, ApplicationInfo, getCategoryTitle, category, Android.Content.PM.ApplicationCategories 26, android.content.pm, LauncherApps, getApplicationInfo, flags, Android.Content.PM.PackageInfoFlags -26, android.icu.util, TimeZone, getTimeZone, type, Android.Icu.Util.TimeZoneType 26, android.media, AudioAttributes, getVolumeControlStream, return, Android.Media.Stream 26, android.media, AudioAttributes, getVolumeControlStream, return, Android.Media.Stream diff --git a/build-tools/scripts/BuildEverything.mk b/build-tools/scripts/BuildEverything.mk index d3933ea1cee..65a6fb3c20d 100644 --- a/build-tools/scripts/BuildEverything.mk +++ b/build-tools/scripts/BuildEverything.mk @@ -23,7 +23,7 @@ ALL_PLATFORM_IDS = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # supported api levels ALL_FRAMEWORKS = _ _ _ _ _ _ _ _ _ v2.3 _ _ _ _ v4.0.3 v4.1 v4.2 v4.3 v4.4 v4.4.87 v5.0 v5.1 v6.0 v7.0 v7.1 v8.0 API_LEVELS = 10 15 16 17 18 19 20 21 22 23 24 25 26 -STABLE_API_LEVELS = 10 15 16 17 18 19 20 21 22 23 24 25 +STABLE_API_LEVELS = 10 15 16 17 18 19 20 21 22 23 24 25 26 ## The preceding values *must* use SPACE, **not** TAB, to separate values. diff --git a/src/Mono.Android/Java.Lang/StringBuffer.cs b/src/Mono.Android/Java.Lang/StringBuffer.cs new file mode 100644 index 00000000000..777a7a38381 --- /dev/null +++ b/src/Mono.Android/Java.Lang/StringBuffer.cs @@ -0,0 +1,19 @@ +#if ANDROID_26 + +// It is introduced since API 26 not because of new member in StringBuffer +// but in AbstractStringBuilder which is nonpublic and affects the generated API. + +using System; + +namespace Java.Lang +{ + public partial class StringBuffer + { + public IAppendable Append (string s, int start, int end) + { + return Append (new Java.Lang.String (s), start, end); + } + } +} + +#endif diff --git a/src/Mono.Android/Java.Lang/StringBuilder.cs b/src/Mono.Android/Java.Lang/StringBuilder.cs new file mode 100644 index 00000000000..dbc3af843b9 --- /dev/null +++ b/src/Mono.Android/Java.Lang/StringBuilder.cs @@ -0,0 +1,19 @@ +#if ANDROID_26 + +// It is introduced since API 26 not because of new member in StringBuffer +// but in AbstractStringBuilder which is nonpublic and affects the generated API. + +using System; + +namespace Java.Lang +{ + public partial class StringBuilder + { + public IAppendable Append (string s, int start, int end) + { + return Append (new Java.Lang.String (s), start, end); + } + } +} + +#endif diff --git a/src/Mono.Android/Java.Nio/FileChannel.cs b/src/Mono.Android/Java.Nio/FileChannel.cs new file mode 100644 index 00000000000..224ad9d151d --- /dev/null +++ b/src/Mono.Android/Java.Nio/FileChannel.cs @@ -0,0 +1,34 @@ +#if ANDROID_25 + +using System; + +namespace Java.Nio.Channels +{ + public partial class FileChannel + { +/* +This had to be added for API compatibility with earlier API Levels. + +It is a newly introduced breakage for OpenJDK migration. +FileChannel now implements SeekableByteChannel, which never existed, and +they require those methods to return ISeekableByteChannel in C#, not +FileChannel whereas FileChannel is ISeekableByteChannel. + +So they were first changed in the metadata fixup first, but then it resulted +in the API breakage. Therefore, I'm reverting the changes in metadata +and adding explicit interface methods here instead. +*/ + ISeekableByteChannel ISeekableByteChannel.Position (long newPosition) + { + return Position (newPosition); + } + + ISeekableByteChannel ISeekableByteChannel.Truncate (long size) + { + return Truncate (size); + } + } +} + +#endif + diff --git a/src/Mono.Android/Mono.Android.csproj b/src/Mono.Android/Mono.Android.csproj index 7041a08c91a..63dfa4150f7 100644 --- a/src/Mono.Android/Mono.Android.csproj +++ b/src/Mono.Android/Mono.Android.csproj @@ -267,11 +267,14 @@ + + + diff --git a/src/Mono.Android/metadata b/src/Mono.Android/metadata index 404d67e2865..1bab91e0d68 100644 --- a/src/Mono.Android/metadata +++ b/src/Mono.Android/metadata @@ -77,10 +77,6 @@ Please use SetSystemScope() instead. This setter is not really public in Android API and will vanish in the future versions. - - Java.Nio.Channels.ISeekableByteChannel - Java.Nio.Channels.ISeekableByteChannel - @@ -1362,8 +1358,9 @@ former non-generic version. So they should be regarded as identical. Also, for this method we have *manually* bound generic method. - We could make fixes in api-merge, but manual fix is 100x simpler. --> - - android.view.View + We could make fixes in api-merge, but manual fix is 100x simpler. + Sadly api-merge is processed before metadata fixup, so it cannot be simple overload removal. --> + + android.view.View diff --git a/src/Mono.Android/methodmap.csv b/src/Mono.Android/methodmap.csv index c594241a704..2ae5043c479 100644 --- a/src/Mono.Android/methodmap.csv +++ b/src/Mono.Android/methodmap.csv @@ -2271,7 +2271,8 @@ 26, android.telecom, Call.Callback, onRttInitiationFailure, reason, Android.Telecom.RttSessionModifyResult 26, android.telephony, TelephonyManager.UssdResponseCallback, onReceiveUssdResponseFailed, failureCode, Android.Telephony.UssdResultCode -26, android.icu.util, TimeZone, getTimeZone, type, Android.Icu.Util.TimeZoneType +// cannot change this at this state. +// 24, android.icu.util, TimeZone, getTimeZone, type, Android.Icu.Util.TimeZoneType 26, android.icu.util, UniversalTimeScale, bigDecimalFrom, timeScale, Android.Icu.Util.UniversalTimeScaleType 26, android.icu.util, UniversalTimeScale, from, timeScale, Android.Icu.Util.UniversalTimeScaleType 26, android.icu.util, UniversalTimeScale, getTimeScaleValue, scale, Android.Icu.Util.UniversalTimeScaleType @@ -2316,7 +2317,6 @@ 26, android.content, Intent, removeFlags, flags, Android.Content.ActivityFlags 26, android.content.pm, ApplicationInfo, getCategoryTitle, category, Android.Content.PM.ApplicationCategories 26, android.content.pm, LauncherApps, getApplicationInfo, flags, Android.Content.PM.PackageInfoFlags -26, android.icu.util, TimeZone, getTimeZone, type, Android.Icu.Util.TimeZoneType 26, android.media, AudioAttributes, getVolumeControlStream, return, Android.Media.Stream 26, android.media, AudioAttributes, getVolumeControlStream, return, Android.Media.Stream