Skip to content

Commit e33eb53

Browse files
atsushienojonpryor
authored andcommitted
[Mono.Android] API-26 Enumification (#662)
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=30909 Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=51293 Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=55473 Bump to xamarin-android-api-compatibility/master/6fe9b17f. Add `Documentation/HowToAddNewApiLevel.md`, to describe the process for binding new API levels, including enumification. Enumify API-26. Update `build-tools/enumification-helpers` to support the latest droiddoc `packages.html` format. API-26 changed `Activity.findViewById(int)` to be a generic method. Remove the `<typeParameters/>` element and "fix" the return type so that we don't break API compatibility, as `generator` doesn't currently do anything sane here. (Specifically, all generic paramaters are currently bound as `Java.Lang.Object`, *even if* the type parameter has a constraint which provides a more specific type!) Fix binding of `Java.Nio.FileChannel` so it can be actually bound, related `SeekableByteChannel` support fixes. Remove `//implements[@name='AutoCloseable']` and `//implements[@name='Destryable']`, as they add Java `default` interface methods which can't be sanely supported at this time. Update `api-merge` to change `default` interface methods to non-`default` methods when merging with an older API level which contained the non-`default` interface method. This preserves backward compatibility with existing assemblies and source code. Remove the associated workarounds. Bump xamarin-android-api-compatibility to check against the latest-and-greatest API-26 binding.
1 parent 6189f97 commit e33eb53

File tree

23 files changed

+1314
-11247
lines changed

23 files changed

+1314
-11247
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
2+
# How to deal with new API Level
3+
4+
## This documentation is incomplete
5+
6+
In Xamarin ages, we used to have (more complete) API upgrade guide internally. But since then we switched to new xamarin-android repository which entirely changed the build system from Makefile to MSBuild solution, as well as the managed API for manipulating Android SDK, the old documentation almost does not make sense anymore. Even though I am writing this documentation, I don't know everything required (nor those who changed the build system didn't care about API upgrades).
7+
8+
Hence, this documentation is written from the ground, exploring everything around.
9+
10+
And since the build system has changed between the first preview of Android O and the latest Android O preview (3), and it is quite possible that the build system changes over and over again, it might still not make much sense in the future.
11+
12+
## Steps
13+
14+
Anyhow, this commit would tell you what needs to be changed when the new API preview arrives (and that becomes stable): https://github.com/xamarin/xamarin-android/pull/642
15+
16+
1) Add/update new download to build-tools/android-toolchain.
17+
The new API archive should be found on the web repository description
18+
that Google Android SDK Manager uses (which can be now shown as part
19+
of SDK Manager options in Android Studio).
20+
21+
As of Android O ages, it could be found at https://dl-ssl.google.com/android/repository/repository2-1.xml . It used to be different repository description URL, and it will be different URL in the future.
22+
23+
2) Create and add api-O.xml.in under src/Mono.Android/Profile directory.
24+
It can be done from within `build-tools/api-xml-adjuster` directory. See `README.md` in that directory for details. You will have to make changes to Makefile in that directory to generate it. Also note that it often happens that Google does not ship documentation archive (!) and in such case we will have to scrape DroidDoc from the web and create our own docs archive.
25+
26+
3) Review new API (or review the changes in case of API updates).
27+
28+
Some of the changes are caused by API removal. Usually they come with
29+
"deprecated" state in the previous API Level first, but that's not always true.
30+
31+
4) enumification: See `build-tools/enumification-helpers/README`.
32+

build-tools/api-merge/ApiDescription.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,21 @@ public void Merge (string apiLocation)
121121
var sa = smember.Attribute (a.Name);
122122
if (sa == null)
123123
smember.Add (a);
124-
else if (sa.Value != a.Value)
125-
sa.SetValue (a.Value);
126-
}
124+
else {
125+
// An interface method can become a default interface method in
126+
// the later API Levels, but since such a method still has to be
127+
// explicitly implemented in older API versions, they should be non-default.
128+
// So, do not change this attribute if it is an interface method.
129+
if (sa.Name.LocalName == "abstract") {
127130
#if KEEP_OLD_WRONG_COMPATIBILITY
128-
var isAbstract = smember.Attribute ("abstract");
129-
if (isAbstract != null)
130-
isAbstract.Value = nmember.Attribute ("abstract").Value;
131+
if (stype.Name.LocalName != "interface")
132+
sa.Value = a.Value;
131133
#endif
134+
}
135+
else if (sa.Value != a.Value)
136+
sa.SetValue (a.Value);
137+
}
138+
}
132139
// This is required to workaround the
133140
// issue that API Level 20 does not offer
134141
// reference docs and we use API Level 21
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
map.ext.csv
2+
const-list-*.xml
3+
remaining-int-methods.txt
4+
*.exe
5+
*.mdb
6+
*.pdb
7+

build-tools/enumification-helpers/Makefile

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
topdir = ../..
22

3-
API_LEVEL = 25
4-
API_LEVEL_NAME = 25
3+
API_LEVEL = 26
4+
API_LEVEL_NAME = 26
5+
6+
CSCOMPILE = csc -debug:portable
57

68
CONFIGURATION = Debug
7-
API_XML_ANALYZER_DIR = $(topdir)/build-tools/api-xml-adjuster
8-
JAR2XML_DIR = $(topdir)/external/jar2xml
9+
DOCS_DIR=~/android-toolchain/docs/docs-api-$(API_LEVEL_NAME)
910

1011
CONST_MAPPER_SOURCES = \
1112
generate-const-mapping.cs \
@@ -17,20 +18,20 @@ all:: map.ext.csv remaining-int-consts.txt remaining-int-methods-filtered.txt
1718
#enum mappings
1819

1920
generate-const-list.exe: generate-const-list.cs
20-
mcs generate-const-list.cs -debug
21+
$(CSCOMPILE) generate-const-list.cs
2122

2223
const-list-$(API_LEVEL).xml: generate-const-list.exe
23-
mono --debug generate-const-list.exe $(API_XML_ANALYZER_DIR)/docs-api-$(API_LEVEL_NAME)/reference/ -v > const-list-$(API_LEVEL).xml || rm const-list-$(API_LEVEL).xml
24+
mono --debug generate-const-list.exe $(DOCS_DIR)/reference/ -v > const-list-$(API_LEVEL).xml || rm const-list-$(API_LEVEL).xml
2425

2526
generate-intermediary-enum-candidates.exe : generate-intermediary-enum-candidates.cs
26-
mcs generate-intermediary-enum-candidates.cs -debug
27+
$(CSCOMPILE) generate-intermediary-enum-candidates.cs
2728

2829
#it is obsolete
2930
intermediary-enum-candidates.xml: generate-intermediary-enum-candidates.exe
3031
mono --debug generate-intermediary-enum-candidates.exe $(topdir)/src/Mono.Android/api-$(API_LEVEL).xml.in > intermediary-enum-candidates.xml || rm intermediary-enum-candidates.xml
3132

3233
generate-const-mapping.exe: $(CONST_MAPPER_SOURCES)
33-
mcs $(CONST_MAPPER_SOURCES) -debug
34+
$(CSCOMPILE) $(CONST_MAPPER_SOURCES)
3435

3536
map.ext.csv: generate-const-mapping.exe enum-conversion-mappings.xml const-list-$(API_LEVEL).xml
3637
mono --debug generate-const-mapping.exe enum-conversion-mappings.xml const-list-$(API_LEVEL).xml > map.ext.csv || rm map.ext.csv
@@ -48,22 +49,22 @@ remaining-int-consts.txt: ../../src/Mono.Android/obj/$(CONFIGURATION)/android-$(
4849

4950
# method mappings
5051
generate-intermediary-doc-enum-mapping.exe: generate-intermediary-doc-enum-mapping.cs
51-
mcs generate-intermediary-doc-enum-mapping.cs -debug
52+
$(CSCOMPILE) generate-intermediary-doc-enum-mapping.cs
5253

5354
generate-enumlist-to-query.exe : generate-enumlist-to-query.cs
54-
mcs generate-enumlist-to-query.cs -debug
55+
$(CSCOMPILE) generate-enumlist-to-query.cs
5556

5657
generate-intermediary-method-mapping.exe: generate-intermediary-method-mapping.cs
57-
mcs generate-intermediary-method-mapping.cs -debug
58+
$(CSCOMPILE) generate-intermediary-method-mapping.cs
5859

5960
intermediary-enum-list.txt: generate-enumlist-to-query.exe
6061
mono --debug generate-enumlist-to-query.exe const-list-$(API_LEVEL).xml > intermediary-enum-list.txt || rm intermediary-enum-list.txt
6162

6263
intermediary-doc-enum-mapping.tsv: generate-intermediary-doc-enum-mapping.exe intermediary-enum-list.txt
63-
mono --debug generate-intermediary-doc-enum-mapping.exe $(API_XML_ANALYZER_DIR)/docs-api-$(API_LEVEL_NAME)/reference intermediary-enum-list.txt > intermediary-doc-enum-mapping.tsv || rm intermediary-doc-enum-mapping.tsv
64+
mono --debug generate-intermediary-doc-enum-mapping.exe $(DOCS_DIR)/reference intermediary-enum-list.txt > intermediary-doc-enum-mapping.tsv || rm intermediary-doc-enum-mapping.tsv
6465

6566
intermediary-method-mapping.txt: generate-intermediary-method-mapping.exe
66-
mono --debug generate-intermediary-method-mapping.exe intermediary-doc-enum-mapping.tsv const-list-$(API_LEVEL).xml $(API_XML_ANALYZER_DIR)/docs-api-$(API_LEVEL_NAME)/reference > intermediary-method-mapping.txt || rm intermediary-method-mapping.txt
67+
mono --debug generate-intermediary-method-mapping.exe intermediary-doc-enum-mapping.tsv const-list-$(API_LEVEL).xml $(DOCS_DIR)/reference > intermediary-method-mapping.txt || rm intermediary-method-mapping.txt
6768

6869
intermediary-field-candidates.txt: intermediary-method-mapping.txt
6970
grep "#[a-z]" intermediary-method-mapping.txt | grep -v '(' > intermediary-field-candidates.txt

build-tools/enumification-helpers/README

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,16 @@ The results are to be saved as "map.ext.csv" and "methodmap.ext.csv" that are to
193193
after "// automatically generated ones" line) just edit map.csv.
194194
- then run "make API_LEVELS=[latest] clean all" in src/Mono.Android
195195
to build enumified dll.
196+
- note tht API Level description in the API docs are used to
197+
become part of the CSV entry. The first item is the API Level.
198+
That often brings problem. This is what happened when API Level
199+
26 as stable has arrived: Google had published "android-26" API
200+
which used to be "android-O", they still hadn't published the
201+
corresponding docs and therefore the docs say "O" but the actual
202+
API was "26". That later brought confusion at generator.exe ran.
203+
To workaround this issue, replace the wrong API level specifier
204+
(e.g. "O") with the actual API level (e.g. "26"). Use regex like
205+
/^O/26/ to achieve this.
196206
- go back to this directory and rebuild remaining-int-consts.txt
197207
and check if the enumified lines disappeared.
198208
- There are some constaints that are NOT enumified
@@ -221,6 +231,15 @@ The results are to be saved as "map.ext.csv" and "methodmap.ext.csv" that are to
221231
convert to enums" methods, or blacklist-field.txt for fields.
222232
- in general those notes do not describe *everything*. git diff
223233
would tell what is new and what should be taken care this time.
234+
- Here is how I worked on it at API Level 26 to add new lines to methodmap.ext.csv:
235+
- Read git diff on remaining-int-consts.txt to iterate all the new enum types.
236+
- For each new enum type that (typically) has prefix P_ in type T, I run `grep -R P_ | grep T | grep "\w*.html:"` in the local reference docs, to see which documentation HTML mention that const (I ran the command on GNOME terminal, so I got the final grep matches with color highlights).
237+
- And for each HTML doc, look up that const and add records to methodmap.ext.csv.
238+
- I usually bring in mistakes. When there are wrong const mappings, they will result in binding generator warnings for unmatched XPath selectors that you can find them by looking up enummetadata.
239+
- For method mappings, mistakes can be twofolds:
240+
- For the wrong matching, you'll see them as binding generator warnings for unmatched XPath selectors just like const mappings.
241+
- For the wrong replacement enum type, that's NOT going to be unmatched XPath. Instead it will result in a reference to missing type warning that can be still found as a generator warning (but harder to find).
242+
- It is often hard to identify why the mappings are regarded as invalid; sometimes Google API reference tells you lies(!) that there are some methods that actually don't exist(!). You'd like to check `obj/Debug/android-*/api.xml`, `obj/Debug/android-*/api.xml.fixed` (XML after applying metadata fixup) or `Profiles/api-*.xml.in` (for "raw" API data before `api-merge` step).
224243
- At some stage, go to src/Mono.Android and append
225244
methodmap.ext.csv contents to methodmap.csv and run
226245
"make API_LEVELS=[latest] clean all" to get enumified dll.

0 commit comments

Comments
 (0)