Skip to content

Commit 9e6be77

Browse files
committed
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 = <span class='removed removed-inline removed-breaking-inline'>130</span> <span class='added '>230</span> Google changed the value! public RemoteInput.Builder SetAllowFreeFormInput (bool <span class='removed removed-inline removed-breaking-inline'>allowFreeFormInput</span> <span class='added '>allowFreeFormTextInput</span>) 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. <span class='removed removed-method breaking' data-is-breaking>public virtual void OnServiceAdded (ProfileState status, BluetoothGattService service);</span> It is actually a bugfix: https://bugzilla.xamarin.com/show_bug.cgi?id=55473 public <span class='removed removed-inline removed-breaking-inline'>AdvertiseTx</span> <span class='added '>int</span> 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 <span class='removed removed-inline removed-breaking-inline'>url</span> <span class='added '>uri</span>, string[] projection, string selection, string[] selectionArgs, string sortOrder, Android.OS.CancellationSignal cancellationSignal) public virtual void OnError (string <span class='removed removed-inline removed-breaking-inline'>itemId</span> <span class='added '>mediaId</span>) public virtual bool EnableNetwork (int netId, bool <span class='removed removed-inline removed-breaking-inline'>disableOthers</span> <span class='added '>attemptConnect</span>) public virtual SubscriptionInfo GetActiveSubscriptionInfoForSimSlotIndex (int <span class='removed removed-inline removed-breaking-inline'>slotIdx</span> <span class='added '>slotIndex</span>) public virtual string GetDeviceId (int <span class='removed removed-inline removed-breaking-inline'>slotId</span> <span class='added '>slotIndex</span>) public virtual void SetMaxEms (int <span class='removed removed-inline removed-breaking-inline'>maxems</span> <span class='added '>maxEms</span>) public virtual void SetMaxHeight (int <span class='removed removed-inline removed-breaking-inline'>maxHeight</span> <span class='added '>maxPixels</span>) (... and all those relevant methods on Android.Widget.TextView) public bool IsAnnotationPresent (Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>) public bool IsAssignableFrom (Class <span class='removed removed-inline removed-breaking-inline'>c</span> <span class='added '>cls</span>) public bool IsInstance (Object <span class='removed removed-inline removed-breaking-inline'>object</span> <span class='added '>obj</span>) public virtual bool IsAnnotationPresent (Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>) public virtual void TraceInstructions (bool <span class='removed removed-inline removed-breaking-inline'>enable</span> <span class='added '>on</span>) public virtual void TraceMethodCalls (bool <span class='removed removed-inline removed-breaking-inline'>enable</span> <span class='added '>on</span>) public virtual bool IsAnnotationPresent (Java.Lang.Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>) public Java.Lang.Object NewInstance (Java.Lang.Object[] <span class='removed removed-inline removed-breaking-inline'>args</span> <span class='added '>initargs</span>) public string GetDisplayScript (Locale <span class='removed removed-inline removed-breaking-inline'>locale</span> <span class='added '>inLocale</span>) public string GetDisplayVariant (Locale <span class='removed removed-inline removed-breaking-inline'>locale</span> <span class='added '>inLocale</span>) public virtual int NextInt (int <span class='removed removed-inline removed-breaking-inline'>n</span> <span class='added '>bound</span>) public CopyOnWriteArrayList (Java.Lang.Object[] <span class='removed removed-inline removed-breaking-inline'>array</span> <span class='added '>toCopyIn</span>) (... and all those lines in Java.Util.Concurrent.CopyOnWriteArrayList) They are all parameter name fixes in Android API. MaskFlags = <span class='removed removed-inline removed-breaking-inline'>4080</span> <span class='added '>65520</span> Google changed the constant value here too. Well, it should. <span class='added added-interface breaking' data-is-breaking>Java.Lang.IAutoCloseable</span> 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. <span class='added added-method breaking' data-is-breaking>public virtual View KeyboardNavigationClusterSearch (View p0, FocusSearchDirection p1);</span> 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! dotnet/java-interop#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. <span class='removed removed-method breaking' data-is-breaking>public IAppendable Append (string s, int start, int end);</span> Fixed: see src/Mono.Android/Java.Lang/StringBuffer.cs and src/Mono.Android/Java.Lang/StringBuilder.cs for details. <h3>Removed Type <span class='breaking' data-is-breaking>Java.Lang.Reflect.Constructor.InterfaceConsts</span></h3> <h3>Removed Type <span class='breaking' data-is-breaking>Java.Lang.Reflect.Method.InterfaceConsts</span></h3> 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. <span class='removed removed-method breaking' data-is-breaking>public virtual bool IsAnnotationPresent (Java.Lang.Class annotationClass);</span> <span class='removed removed-method breaking' data-is-breaking>public virtual void AddPropertyChangeListener (Java.Beans.IPropertyChangeListener listener);</span> <span class='removed removed-method breaking' data-is-breaking>public virtual void RemovePropertyChangeListener (Java.Beans.IPropertyChangeListener listener);</span> (in both Pack200.IPacker and Pack200.IUnpacker) <span class='removed removed-property breaking' data-is-breaking>public virtual bool IsDestroyed { get; }</span> <span class='removed removed-method breaking' data-is-breaking>public virtual void Destroy ();</span> 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. <span class='added added-interface breaking' data-is-breaking>IAnnotatedElement</span> 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. <span class='removed removed-method breaking' data-is-breaking>public virtual FileChannel Position (long newPosition);</span> <span class='removed removed-method breaking' data-is-breaking>public virtual FileChannel Truncate (long size);</span> <span class='removed removed-method breaking' data-is-breaking>public System.Threading.Tasks.Task&lt;FileChannel&gt; TruncateAsync (long size);</span> 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. <span class='added added-interface breaking' data-is-breaking>Javax.Security.Auth.IDestroyable</span> This should not be reported because all those interface methods are default! <h3>Removed Type <span class='breaking' data-is-breaking>Android.Service.Quicksettings.TileState</span></h3></div> <!-- end namespace Android.Service.Quicksettings --> I explicitly removed this. It had been marked as [Obsolete].
1 parent 0a0aa95 commit 9e6be77

File tree

8 files changed

+84
-12
lines changed

8 files changed

+84
-12
lines changed

build-tools/enumification-helpers/methodmap.ext.csv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,7 +1675,8 @@
16751675
26, android.telecom, Call.Callback, onRttInitiationFailure, reason, Android.Telecom.RttSessionModifyResult
16761676
26, android.telephony, TelephonyManager.UssdResponseCallback, onReceiveUssdResponseFailed, failureCode, Android.Telephony.UssdResultCode
16771677

1678-
26, android.icu.util, TimeZone, getTimeZone, type, Android.Icu.Util.TimeZoneType
1678+
// cannot change this at this state.
1679+
// 24, android.icu.util, TimeZone, getTimeZone, type, Android.Icu.Util.TimeZoneType
16791680
26, android.icu.util, UniversalTimeScale, bigDecimalFrom, timeScale, Android.Icu.Util.UniversalTimeScaleType
16801681
26, android.icu.util, UniversalTimeScale, from, timeScale, Android.Icu.Util.UniversalTimeScaleType
16811682
26, android.icu.util, UniversalTimeScale, getTimeScaleValue, scale, Android.Icu.Util.UniversalTimeScaleType
@@ -1720,7 +1721,6 @@
17201721
26, android.content, Intent, removeFlags, flags, Android.Content.ActivityFlags
17211722
26, android.content.pm, ApplicationInfo, getCategoryTitle, category, Android.Content.PM.ApplicationCategories
17221723
26, android.content.pm, LauncherApps, getApplicationInfo, flags, Android.Content.PM.PackageInfoFlags
1723-
26, android.icu.util, TimeZone, getTimeZone, type, Android.Icu.Util.TimeZoneType
17241724

17251725
26, android.media, AudioAttributes, getVolumeControlStream, return, Android.Media.Stream
17261726
26, android.media, AudioAttributes, getVolumeControlStream, return, Android.Media.Stream

build-tools/scripts/BuildEverything.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ ALL_PLATFORM_IDS = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
2323
# supported api levels
2424
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
2525
API_LEVELS = 10 15 16 17 18 19 20 21 22 23 24 25 26
26-
STABLE_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 26
2727

2828
## The preceding values *must* use SPACE, **not** TAB, to separate values.
2929

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#if ANDROID_26
2+
3+
// It is introduced since API 26 not because of new member in StringBuffer
4+
// but in AbstractStringBuilder which is nonpublic and affects the generated API.
5+
6+
using System;
7+
8+
namespace Java.Lang
9+
{
10+
public partial class StringBuffer
11+
{
12+
public IAppendable Append (string s, int start, int end)
13+
{
14+
return Append (new Java.Lang.String (s), start, end);
15+
}
16+
}
17+
}
18+
19+
#endif
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#if ANDROID_26
2+
3+
// It is introduced since API 26 not because of new member in StringBuffer
4+
// but in AbstractStringBuilder which is nonpublic and affects the generated API.
5+
6+
using System;
7+
8+
namespace Java.Lang
9+
{
10+
public partial class StringBuilder
11+
{
12+
public IAppendable Append (string s, int start, int end)
13+
{
14+
return Append (new Java.Lang.String (s), start, end);
15+
}
16+
}
17+
}
18+
19+
#endif
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#if ANDROID_26
2+
3+
using System;
4+
5+
namespace Java.Nio.Channels
6+
{
7+
public partial class FileChannel
8+
{
9+
/*
10+
This had to be added for API compatibility with earlier API Levels.
11+
12+
It is a newly introduced breakage for OpenJDK migration.
13+
FileChannel now implements SeekableByteChannel, which never existed, and
14+
they require those methods to return ISeekableByteChannel in C#, not
15+
FileChannel whereas FileChannel is ISeekableByteChannel.
16+
17+
So they were first changed in the metadata fixup first, but then it resulted
18+
in the API breakage. Therefore, I'm reverting the changes in metadata
19+
and adding explicit interface methods here instead.
20+
*/
21+
ISeekableByteChannel ISeekableByteChannel.Position (long newPosition)
22+
{
23+
return Position (newPosition);
24+
}
25+
26+
ISeekableByteChannel ISeekableByteChannel.Truncate (long size)
27+
{
28+
return Truncate (size);
29+
}
30+
}
31+
}
32+
33+
#endif
34+

src/Mono.Android/Mono.Android.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,11 +267,14 @@
267267
<Compile Include="Java.Lang\RuntimeException.cs" />
268268
<Compile Include="Java.Lang\Short.cs" />
269269
<Compile Include="Java.Lang\String.cs" />
270+
<Compile Include="Java.Lang\StringBuffer.cs" />
271+
<Compile Include="Java.Lang\StringBuilder.cs" />
270272
<Compile Include="Java.Lang\Thread.cs" />
271273
<Compile Include="Java.Lang\Throwable.cs" />
272274
<Compile Include="Java.Lang.Reflect\InvocationTargetException.cs" />
273275
<Compile Include="Java.Nio\Buffer.cs" />
274276
<Compile Include="Java.Nio\CharBuffer.cs" />
277+
<Compile Include="Java.Nio\FileChannel.cs" />
275278
<Compile Include="Java.Security\IdentityScope.cs" />
276279
<Compile Include="Java.Util\Spliterators.cs" />
277280
<Compile Include="Java.Util.Concurrent.Atomic\AtomicInteger.cs" />

src/Mono.Android/metadata

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,6 @@
7777
Please use SetSystemScope() instead. This setter is not really public in Android API and will vanish in the future versions.
7878
</attr>
7979

80-
<!-- return type in a method in a class cannot be more specific in C# -->
81-
<attr path="/api/package[@name='java.nio.channels']/class[@name='FileChannel']/method[@name='position' and parameter[1]/@type='long']" name="managedReturn" api-since="24">Java.Nio.Channels.ISeekableByteChannel</attr>
82-
<attr path="/api/package[@name='java.nio.channels']/class[@name='FileChannel']/method[@name='truncate']" name="managedReturn" api-since="24">Java.Nio.Channels.ISeekableByteChannel</attr>
83-
8480
<!-- Also, it seems to lack some non-public types even in android.jar but the derived types still reference...!
8581
- java.lang.ClassNotFoundException is marked as derived from java.lang.ReflectiveOperationException which does not exist.
8682
Also, this class has disappeared at some stage. -->
@@ -1362,8 +1358,9 @@
13621358
former non-generic version. So they should be regarded as identical.
13631359
Also, for this method we have *manually* bound generic method.
13641360

1365-
We could make fixes in api-merge, but manual fix is 100x simpler. -->
1366-
<remove-node path="/api/package[@name='android.view']/class/method[@name='findViewById']/typeParameters" api-since="26" />
1367-
<attr path="/api/package[@name='android.view']/class/method[@name='findViewById']" name="return" api-since="26">android.view.View</attr>
1361+
We could make fixes in api-merge, but manual fix is 100x simpler.
1362+
Sadly api-merge is processed before metadata fixup, so it cannot be simple overload removal. -->
1363+
<remove-node path="/api/package/class/method[@name='findViewById' or @name='onFindViewById' or @name='findViewWithTag']/typeParameters" api-since="26" />
1364+
<attr path="/api/package/class/method[@name='findViewById' or @name='onFindViewById' or @name='findViewWithTag']" name="return" api-since="26">android.view.View</attr>
13681365

13691366
</metadata>

src/Mono.Android/methodmap.csv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2271,7 +2271,8 @@
22712271
26, android.telecom, Call.Callback, onRttInitiationFailure, reason, Android.Telecom.RttSessionModifyResult
22722272
26, android.telephony, TelephonyManager.UssdResponseCallback, onReceiveUssdResponseFailed, failureCode, Android.Telephony.UssdResultCode
22732273

2274-
26, android.icu.util, TimeZone, getTimeZone, type, Android.Icu.Util.TimeZoneType
2274+
// cannot change this at this state.
2275+
// 24, android.icu.util, TimeZone, getTimeZone, type, Android.Icu.Util.TimeZoneType
22752276
26, android.icu.util, UniversalTimeScale, bigDecimalFrom, timeScale, Android.Icu.Util.UniversalTimeScaleType
22762277
26, android.icu.util, UniversalTimeScale, from, timeScale, Android.Icu.Util.UniversalTimeScaleType
22772278
26, android.icu.util, UniversalTimeScale, getTimeScaleValue, scale, Android.Icu.Util.UniversalTimeScaleType
@@ -2316,7 +2317,6 @@
23162317
26, android.content, Intent, removeFlags, flags, Android.Content.ActivityFlags
23172318
26, android.content.pm, ApplicationInfo, getCategoryTitle, category, Android.Content.PM.ApplicationCategories
23182319
26, android.content.pm, LauncherApps, getApplicationInfo, flags, Android.Content.PM.PackageInfoFlags
2319-
26, android.icu.util, TimeZone, getTimeZone, type, Android.Icu.Util.TimeZoneType
23202320

23212321
26, android.media, AudioAttributes, getVolumeControlStream, return, Android.Media.Stream
23222322
26, android.media, AudioAttributes, getVolumeControlStream, return, Android.Media.Stream

0 commit comments

Comments
 (0)