Skip to content
This repository has been archived by the owner on Mar 8, 2021. It is now read-only.

Commit

Permalink
Fix xamarin-android run-api-compatibility-tests
Browse files Browse the repository at this point in the history
Context: dotnet/android#1089

What is the purpose of the xamarin-android-api-compatibility repo?
To ensure that we don't accidentally break API, both for the latest
supported API level, and *between* API level binding assemblies.

How's that working out for us?

It could be better.

Commit e353872 was due to a discovery that `mono-api-html` behavior
had changed: it *used* to emit separate "Removed" and "Added"
declarations whenever a method was changed. Then it started emitting
"Modified" sections, but we weren't aware of this change. The result
was an [accidental API break][pr-771], and a change to start looking
for `data-is-breaking` instead of `>Removed`.

[pr-771]: dotnet/android#771 (comment)

*Then* we learned that `make check-inter-api-level` was broken, due to
bad `test` logic. This was fixed in 6dfba92.

The problem is that xamarin-android has not been able to use
[xamarin-android-api-compatibility/master][pr-1078] since 6dfba92 has
been merged, because it found [inter-API level breakage][inter-break]
that we haven't been able to work around, e.g.:

[pr-1078]: dotnet/android#1078
[inter-break]: dotnet/android#1078 (comment)

	<h3>Type Changed: Android.Preferences.CheckBoxPreference</h3>
	Modified base type: <span class='removed removed-inline removed-breaking-inline'>Android.Preferences.Preference</span> <span class='added '>Android.Preferences.TwoStatePreference</span>

The "obvious" solution would have been to use the existing
`inter-api-extra*` files/mechanism to ignore the changes which kept
`make check-inter-api-level` from succeeding, but `mono-api-html`
didn't provide a mechanism to ignore all of those changes.

Doh!

The fix? [Improve `mono-api-html` so it can ignore more][api-ignore]
API artifacts. (Additionally, improve `mono-api-html` so that we can
"scope" what changes we're ignoring, so that e.g. `mono-api-html -r`
can specify the *type* that the ignore should apply to, and not be
matched against *every member in the assembly*.)

[api-ignore]: mono/mono@de4729f

With that infrastructural change in place, update the
`inter-api-extra*` files so that the acceptable changes are ignored,
thus allowing `make check` to run w/o error on xamarin-android/master.

Additionally:

  * The updated `mono-api-html` supports response files. Update the
    `mono-api-html` invocation to provide the `inter-api-extra*` files as
    response files, instead of `cat`ing the `inter-api-extra*` files.
    Eventually, `mono-api-html` may support comments in response files, which
    would allow us to use them.

  * Update `reference/Mono.Android.xml` for `ChoiceMode`.
    Commit 6874e3f updated `Android.Widget.ListView` to use `ChoiceMode`
    instead of `int` for many of the constants. This was inadvertently
    "reverted"/overwrritten in bb8630a.

  * Add support for a new `$(HTML_OUTPUT_DIR)` make variable. If set,
    `mono-api-html`-generated HTML files will be written into the
    `$(HTML_OUTPUT_DIR)` directory.
  • Loading branch information
jonpryor committed Feb 22, 2018
1 parent ba5dc55 commit 2c689ef
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 9 deletions.
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ export OS := $(shell uname)
MONO_API_HTML = mono-api-html
MONO_API_INFO = mono-api-info

HTML_OUTPUT_DIR =

REFERENCE_DIR = reference

ifeq ($(OS),Darwin)
Expand Down Expand Up @@ -94,7 +96,9 @@ check: check-inter-api-level
for file in $(CORE_ASSEMBLIES) $(TFV_ASSEMBLIES) ; do \
if $(MONO_API_HTML) $(REFERENCE_DIR)/$$file.xml temp/$$file.xml --ignore-changes-parameter-names --ignore-nonbreaking | grep '\<data-is-breaking\>' > /dev/null 2>&1 ; then \
echo "ABI BREAK IN: $$file.dll" ; \
$(MONO_API_HTML) $(REFERENCE_DIR)/$$file.xml temp/$$file.xml --ignore-changes-parameter-names --ignore-nonbreaking; \
$(MONO_API_HTML) $(REFERENCE_DIR)/$$file.xml temp/$$file.xml --ignore-changes-parameter-names --ignore-nonbreaking \
$(if $(HTML_OUTPUT_DIR),$(HTML_OUTPUT_DIR)/$$file.html); \
if [ -n "$(HTML_OUTPUT_DIR)" ] ; then cat "$(HTML_OUTPUT_DIR)/$$file.html" ; fi ; \
failed=1; \
fi ; \
done ; \
Expand Down Expand Up @@ -127,14 +131,17 @@ check-inter-api-level: -create-inter-api-infos
cur="inter-apis/$${_frameworks[$$i]}/Mono.Android.xml"; \
extras_in="inter-api-extra-$${_frameworks[$$prev_framework]}-$${_frameworks[$$i]}.txt" ; \
echo "# reading extras from: $$extras_in"; \
extra=`cat $$extras_in 2>/dev/null`; \
extra=`if [ -f $$extras_in ]; then echo @$$extras_in ; fi`; \
out=`mktemp interdiff-XXXXXX.html` ; \
command="$(MONO_API_HTML) \"$$prev\" \"$$cur\" --ignore-changes-parameter-names --ignore-changes-virtual --ignore-changes-property-setters --ignore-nonbreaking $$extra"; \
echo $$command; \
eval $$command > "$$out" 2>&1; \
if grep '\<data-is-breaking\>' $$out > /dev/null 2>&1 ; then \
echo "<h1>### API BREAK BETWEEN $${_frameworks[$$prev_framework]} and $${_frameworks[$$i]}</h1>" ; \
cat $$out; \
if [ -n "$(HTML_OUTPUT_DIR)" ]; then \
cat $$out > "$(HTML_OUTPUT_DIR)/Mono.Android-inter-$${_frameworks[$$prev_framework]}-$${_frameworks[$$i]}.html" ; \
fi; \
failed=1; \
fi ; \
rm $$out; \
Expand Down
10 changes: 10 additions & 0 deletions inter-api-extra-v2.3-v4.0.3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-r "^Android.Preferences.CheckBoxPreference: Modified base type: 'Android.Preferences.Preference' to 'Android.Preferences.TwoStatePreference'"
-r "^Android.Views.Accessibility.AccessibilityEvent: Modified base type: 'Java.Lang.Object' to 'Android.Views.Accessibility.AccessibilityRecord'"
-r "^Android.Text.Method.ArrowKeyMovementMethod: Modified base type: 'Java.Lang.Object' to 'Android.Text.Method.BaseMovementMethod'"
-r "^Android.Text.Method.ScrollingMovementMethod: Modified base type: 'Java.Lang.Object' to 'Android.Text.Method.BaseMovementMethod'"
-r "^Android.Text.ClipboardManager: Modified properties: public bool HasText { get; }"
-r "^Android.Text.ClipboardManager: Modified properties: public Java.Lang.ICharSequence TextFormatted { get; set; }"
-r "^Android.Views.InputEvent: Modified properties: public int DeviceId { get; }"
-r "^Android.Views.InputEvent: Modified properties: public InputSourceType Source { get; }"
-r "^Dalvik.SystemInterop.DexClassLoader: Modified base type: 'Java.Lang.ClassLoader' to 'Dalvik.SystemInterop.BaseDexClassLoader'"
-r "^Dalvik.SystemInterop.PathClassLoader: Modified base type: 'Java.Lang.ClassLoader' to 'Dalvik.SystemInterop.BaseDexClassLoader'"
6 changes: 5 additions & 1 deletion inter-api-extra-v4.0.3-v4.1.txt
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
-r 'public bool FitsSystemWindows \(\);'
-r "^Android.Views.View: Removed methods: public bool FitsSystemWindows \(\);"
-r "Android.OS.Vibrator: Modified properties: public bool HasVibrator { get; }"
-r "Android.OS.Vibrator: Modified methods: public virtual void Cancel \(\);"
-r "Android.OS.Vibrator: Modified methods: public virtual void Vibrate \(long\)"
-r "Android.OS.Vibrator: Modified methods: public virtual void Vibrate \(long\[\], int\)"
94 changes: 94 additions & 0 deletions inter-api-extra-v5.0-v5.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
-r "^Android.Views.Animations.AccelerateDecelerateInterpolator: Modified base type: 'Java.Lang.Object' to 'Android.Views.Animations.BaseInterpolator'"
-r "^Android.Views.Animations.AccelerateInterpolator: Modified base type: 'Java.Lang.Object' to 'Android.Views.Animations.BaseInterpolator'"
-r "^Android.Views.Animations.AnticipateInterpolator: Modified base type: 'Java.Lang.Object' to 'Android.Views.Animations.BaseInterpolator'"
-r "^Android.Views.Animations.AnticipateOvershootInterpolator: Modified base type: 'Java.Lang.Object' to 'Android.Views.Animations.BaseInterpolator'"
-r "^Android.Views.Animations.BounceInterpolator: Modified base type: 'Java.Lang.Object' to 'Android.Views.Animations.BaseInterpolator'"
-r "^Android.Views.Animations.CycleInterpolator: Modified base type: 'Java.Lang.Object' to 'Android.Views.Animations.BaseInterpolator'"
-r "^Android.Views.Animations.DecelerateInterpolator: Modified base type: 'Java.Lang.Object' to 'Android.Views.Animations.BaseInterpolator'"
-r "^Android.Views.Animations.LinearInterpolator: Modified base type: 'Java.Lang.Object' to 'Android.Views.Animations.BaseInterpolator'"
-r "^Android.Views.Animations.OvershootInterpolator: Modified base type: 'Java.Lang.Object' to 'Android.Views.Animations.BaseInterpolator'"
-r "^Android.Views.Animations.PathInterpolator: Modified base type: 'Java.Lang.Object' to 'Android.Views.Animations.BaseInterpolator'"
-r "^Android.Webkit.CookieManager: Modified properties: public bool HasCookies { get; }"
-r "^Android.Webkit.CookieManager: Modified methods: public virtual bool AcceptCookie \(\);"
-r "^Android.Webkit.CookieManager: Modified methods: public virtual bool AcceptThirdPartyCookies \(WebView\);"
-r "^Android.Webkit.CookieManager: Modified methods: public virtual void Flush \(\);"
-r "^Android.Webkit.CookieManager: Modified methods: public virtual string GetCookie \(string\);"
-r "^Android.Webkit.CookieManager: Modified methods: public virtual void RemoveAllCookie \(\);"
-r "^Android.Webkit.CookieManager: Modified methods: public virtual void RemoveAllCookies \(IValueCallback\);"
-r "^Android.Webkit.CookieManager: Modified methods: public virtual void RemoveExpiredCookie \(\);"
-r "^Android.Webkit.CookieManager: Modified methods: public virtual void RemoveSessionCookie \(\);"
-r "^Android.Webkit.CookieManager: Modified methods: public virtual void RemoveSessionCookies \(IValueCallback\);"
-r "^Android.Webkit.CookieManager: Modified methods: public virtual void SetAcceptCookie \(bool\);"
-r "^Android.Webkit.CookieManager: Modified methods: public virtual void SetAcceptThirdPartyCookies \(WebView, bool\);"
-r "^Android.Webkit.CookieManager: Modified methods: public virtual void SetCookie \(string, string\);"
-r "^Android.Webkit.CookieManager: Modified methods: public virtual void SetCookie \(string, string, IValueCallback\);"
-r "^Android.Webkit.WebBackForwardList: Modified properties: public int CurrentIndex { get; }"
-r "^Android.Webkit.WebBackForwardList: Modified properties: public WebHistoryItem CurrentItem { get; }"
-r "^Android.Webkit.WebBackForwardList: Modified properties: public int Size { get; }"
-r "^Android.Webkit.WebBackForwardList: Modified methods: public virtual WebHistoryItem GetItemAtIndex \(int\);"
-r "^Android.Webkit.WebHistoryItem: Modified properties: public Android.Graphics.Bitmap Favicon { get; }"
-r "^Android.Webkit.WebHistoryItem: Modified properties: public string OriginalUrl { get; }"
-r "^Android.Webkit.WebHistoryItem: Modified properties: public string Title { get; }"
-r "^Android.Webkit.WebHistoryItem: Modified properties: public string Url { get; }"
-r "^Android.Webkit.WebIconDatabase: Modified methods: public virtual void Close \(\);"
-r "^Android.Webkit.WebIconDatabase: Modified methods: public virtual void Open \(string\);"
-r "^Android.Webkit.WebIconDatabase: Modified methods: public virtual void ReleaseIconForPageUrl \(string\);"
-r "^Android.Webkit.WebIconDatabase: Modified methods: public virtual void RemoveAllIcons \(\);"
-r "^Android.Webkit.WebIconDatabase: Modified methods: public virtual void RequestIconForPageUrl \(string, WebIconDatabase.IIconListener\);"
-r "^Android.Webkit.WebIconDatabase: Modified methods: public virtual void RetainIconForPageUrl \(string\);"
-r "^Android.Webkit.WebSettings: Modified properties: public bool AllowContentAccess { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public bool AllowFileAccess { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public bool BlockNetworkImage { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public bool BlockNetworkLoads { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public bool BuiltInZoomControls { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public CacheModes CacheMode { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public string CursiveFontFamily { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public bool DatabaseEnabled { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public string DatabasePath { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public int DefaultFixedFontSize { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public int DefaultFontSize { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public string DefaultTextEncodingName { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public WebSettings.ZoomDensity DefaultZoom { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public bool DisplayZoomControls { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public bool DomStorageEnabled { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public string FantasyFontFamily { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public string FixedFontFamily { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public bool JavaScriptCanOpenWindowsAutomatically { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public bool JavaScriptEnabled { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public bool LightTouchEnabled { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public bool LoadWithOverviewMode { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public bool LoadsImagesAutomatically { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public bool MediaPlaybackRequiresUserGesture { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public int MinimumFontSize { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public int MinimumLogicalFontSize { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public string SansSerifFontFamily { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public bool SaveFormData { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public bool SavePassword { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public string SerifFontFamily { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public string StandardFontFamily { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public int TextZoom { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public bool UseWideViewPort { get; set; }"
-r "^Android.Webkit.WebSettings: Modified properties: public string UserAgentString { get; set; }"
-r "^Android.Webkit.WebSettings: Modified methods: public virtual bool EnableSmoothTransition \(\);"
-r "^Android.Webkit.WebSettings: Modified methods: public virtual WebSettings.LayoutAlgorithm GetLayoutAlgorithm \(\);"
-r "^Android.Webkit.WebSettings: Modified methods: public virtual WebSettings.PluginState GetPluginState \(\);"
-r "^Android.Webkit.WebSettings: Modified methods: public virtual void SetAppCacheEnabled \(bool\);"
-r "^Android.Webkit.WebSettings: Modified methods: public virtual void SetAppCacheMaxSize \(long\);"
-r "^Android.Webkit.WebSettings: Modified methods: public virtual void SetAppCachePath \(string\);"
-r "^Android.Webkit.WebSettings: Modified methods: public virtual void SetEnableSmoothTransition \(bool\);"
-r "^Android.Webkit.WebSettings: Modified methods: public virtual void SetGeolocationDatabasePath \(string\);"
-r "^Android.Webkit.WebSettings: Modified methods: public virtual void SetGeolocationEnabled \(bool\);"
-r "^Android.Webkit.WebSettings: Modified methods: public virtual void SetLayoutAlgorithm \(WebSettings.LayoutAlgorithm\);"
-r "^Android.Webkit.WebSettings: Modified methods: public virtual void SetNeedInitialFocus \(bool\);"
-r "^Android.Webkit.WebSettings: Modified methods: public virtual void SetPluginState \(WebSettings.PluginState\);"
-r "^Android.Webkit.WebSettings: Modified methods: public virtual void SetRenderPriority \(WebSettings.RenderPriority\);"
-r "^Android.Webkit.WebSettings: Modified methods: public virtual void SetSupportMultipleWindows \(bool\);"
-r "^Android.Webkit.WebSettings: Modified methods: public virtual void SetSupportZoom \(bool\);"
-r "^Android.Webkit.WebSettings: Modified methods: public virtual bool SupportMultipleWindows \(\);"
-r "^Android.Webkit.WebSettings: Modified methods: public virtual bool SupportZoom \(\);"
-r "^Android.Webkit.WebViewDatabase: Modified properties: public bool HasFormData { get; }"
-r "^Android.Webkit.WebViewDatabase: Modified properties: public bool HasHttpAuthUsernamePassword { get; }"
-r "^Android.Webkit.WebViewDatabase: Modified properties: public bool HasUsernamePassword { get; }"
-r "^Android.Webkit.WebViewDatabase: Modified methods: public virtual void ClearFormData \(\);"
-r "^Android.Webkit.WebViewDatabase: Modified methods: public virtual void ClearHttpAuthUsernamePassword \(\);"
-r "^Android.Webkit.WebViewDatabase: Modified methods: public virtual void ClearUsernamePassword \(\);"
5 changes: 5 additions & 0 deletions inter-api-extra-v5.1-v6.0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-r "^Android.Graphics.Drawables.ClipDrawable: Modified base type: 'Android.Graphics.Drawables.Drawable' to 'Android.Graphics.Drawables.DrawableWrapper'"
-r "^Android.Graphics.Drawables.InsetDrawable: Modified base type: 'Android.Graphics.Drawables.Drawable' to 'Android.Graphics.Drawables.DrawableWrapper'"
-r "^Android.Graphics.Drawables.RotateDrawable: Modified base type: 'Android.Graphics.Drawables.Drawable' to 'Android.Graphics.Drawables.DrawableWrapper'"
-r "^Android.Graphics.Drawables.ScaleDrawable: Modified base type: 'Android.Graphics.Drawables.Drawable' to 'Android.Graphics.Drawables.DrawableWrapper'"
-r "^Android.App.Notification: Modified properties: public int Icon { get; set; }"
1 change: 1 addition & 0 deletions inter-api-extra-v7.0-v7.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-r "^Android.Telecom.RemoteConference: Modified properties: public int ConnectionProperties { get; }"
6 changes: 4 additions & 2 deletions inter-api-extra-v7.1-v8.0.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
-r 'Java.Lang.Reflect.Constructor.InterfaceConsts'
-r 'Java.Lang.Reflect.Method.InterfaceConsts'
-r "Java.Lang.Reflect.Constructor: Modified base type: 'Java.Lang.Reflect.AccessibleObject' to 'Java.Lang.Reflect.Executable'"
-r "Java.Lang.Reflect.Constructor.InterfaceConsts"
-r "Java.Lang.Reflect.Method: Modified base type: 'Java.Lang.Reflect.AccessibleObject' to 'Java.Lang.Reflect.Executable'"
-r "Java.Lang.Reflect.Method.InterfaceConsts"
8 changes: 4 additions & 4 deletions reference/Mono.Android.xml
Original file line number Diff line number Diff line change
Expand Up @@ -777636,7 +777636,7 @@
<interface name="System.IDisposable" />
</interfaces>
<fields>
<field name="ChoiceModeMultiple" attrib="32854" fieldtype="System.Int32" value="2">
<field name="ChoiceModeMultiple" attrib="32854" fieldtype="Android.Widget.ChoiceMode" value="2">
<attributes>
<attribute name="Android.Runtime.RegisterAttribute">
<properties>
Expand All @@ -777645,7 +777645,7 @@
</attribute>
</attributes>
</field>
<field name="ChoiceModeNone" attrib="32854" fieldtype="System.Int32" value="0">
<field name="ChoiceModeNone" attrib="32854" fieldtype="Android.Widget.ChoiceMode" value="0">
<attributes>
<attribute name="Android.Runtime.RegisterAttribute">
<properties>
Expand All @@ -777654,7 +777654,7 @@
</attribute>
</attributes>
</field>
<field name="ChoiceModeSingle" attrib="32854" fieldtype="System.Int32" value="1">
<field name="ChoiceModeSingle" attrib="32854" fieldtype="Android.Widget.ChoiceMode" value="1">
<attributes>
<attribute name="Android.Runtime.RegisterAttribute">
<properties>
Expand Down Expand Up @@ -1108594,4 +1108594,4 @@
</namespace>
</namespaces>
</assembly>
</assemblies>
</assemblies>

0 comments on commit 2c689ef

Please sign in to comment.