Skip to content

Commit 3bf9f56

Browse files
committed
[Xamarin.Android.Build.Utilities] Add AndroidVersions
Commit 8e7d37b is a sign of duplication: in order to use a `Mono.Android.dll` binding assembly, not only do we need to *build* the binding assembly, but we *also* need to update `Xamarin.Android.Build.Utilities.dll` to "know" about the new binding version (to map API level to `$(TargetFrameworkVersion)`). Even "better" (worse), if the new API level is a *preview*, there is no *consistent* API level. For example, with API-O, `android.jar` isn't at `$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar`, where `@API_LEVEL@` is 26 (because various codepaths require that the "api level" be an integer). Instead, it's installed at `$(AndroidSdkDirectory)\platforms\android-O\android.jar`, where `O` is the "id" of the preview API level. This "id" is "leaky", in turn requiring that `Xamarin.Android.Build.Tasks.dll` *also* be updated to deal with the mappings. Even "better" (worse), if we *forget* to cross all our our 't's and dot all of our 'i's, we'll have a binding assembly which can't be used. (Which is why we needed commit 8e7d37b; without it, the API-O binding can't be used!) This is all obviously madness. ;-) Clean this mess up: 1. Update `src/Mono.Android` to create a new `AndroidApiInfo.xml` file within the `$(TargetFrameworkVersion)` directory. This will contain all the information needed to map Android API levels to Ids and Android OS versions and `$(TargetFrameworkVersion)` values. ``` <AndroidApiInfo> <Id>10</Id> <Level>10</Level> <Name>Gingerbread</Name> <Version>v2.3</Version> </AndroidApiInfo> ``` 2. Add a new `Xamarin.Android.Build.Utilities.AndroidVersions` type which looks for and parses these new `AndroidApiInfo.xml` files. 3. Fixup all the other places using `AndroidVersion.KnownVersions` and related members to instead use `AndroidVersions`. 4. Deprecate all the old APIs which rely on hardcoded data. The advantage to all this is that we can support new API level bindings by just building a new `Mono.Android.dll` and placing an `AndroidApiInfo.xml` into the appropriate location (next to `Mono.Android.dll`). No further code changes would be required.
1 parent 8688832 commit 3bf9f56

File tree

12 files changed

+427
-104
lines changed

12 files changed

+427
-104
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ endif
2222

2323
include build-tools/scripts/msbuild.mk
2424
all::
25-
$(MSBUILD) $(MSBUILD_FLAGS) $(SOLUTION)
25+
MSBUILD="$(MSBUILD)" tools/scripts/xabuild $(MSBUILD_FLAGS) $(SOLUTION)
2626

2727
all-tests::
2828
MSBUILD="$(MSBUILD)" tools/scripts/xabuild $(MSBUILD_FLAGS) Xamarin.Android-Tests.sln
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<ItemGroup>
4+
<AndroidApiInfo Include="v1.6">
5+
<Name>Donut</Name>
6+
<Level>4</Level>
7+
<Id>4</Id>
8+
<Stable>True</Stable>
9+
</AndroidApiInfo>
10+
<AndroidApiInfo Include="v2.0">
11+
<Name>Eclair</Name>
12+
<Level>5</Level>
13+
<Id>5</Id>
14+
<Stable>True</Stable>
15+
</AndroidApiInfo>
16+
<AndroidApiInfo Include="v2.0.1">
17+
<Name>Eclair</Name>
18+
<Level>6</Level>
19+
<Id>6</Id>
20+
<Stable>True</Stable>
21+
</AndroidApiInfo>
22+
<AndroidApiInfo Include="v2.1">
23+
<Name>Eclair</Name>
24+
<Level>7</Level>
25+
<Id>7</Id>
26+
<Stable>True</Stable>
27+
</AndroidApiInfo>
28+
<AndroidApiInfo Include="v2.2">
29+
<Name>Froyo</Name>
30+
<Level>8</Level>
31+
<Id>8</Id>
32+
<Stable>True</Stable>
33+
</AndroidApiInfo>
34+
<AndroidApiInfo Include="v2.3">
35+
<Name>Gingerbread</Name>
36+
<Level>10</Level>
37+
<Id>10</Id>
38+
<Stable>True</Stable>
39+
</AndroidApiInfo>
40+
<AndroidApiInfo Include="v3.0">
41+
<Name>Honeycomb</Name>
42+
<Level>11</Level>
43+
<Id>11</Id>
44+
<Stable>True</Stable>
45+
</AndroidApiInfo>
46+
<AndroidApiInfo Include="v3.1">
47+
<Name>Honeycomb</Name>
48+
<Level>12</Level>
49+
<Id>12</Id>
50+
<Stable>True</Stable>
51+
</AndroidApiInfo>
52+
<AndroidApiInfo Include="v3.2">
53+
<Name>Honeycomb</Name>
54+
<Level>13</Level>
55+
<Id>13</Id>
56+
<Stable>True</Stable>
57+
</AndroidApiInfo>
58+
<AndroidApiInfo Include="v4.0">
59+
<Name>Ice Cream Sandwich</Name>
60+
<Level>14</Level>
61+
<Id>14</Id>
62+
<Stable>True</Stable>
63+
</AndroidApiInfo>
64+
<AndroidApiInfo Include="v4.0.3">
65+
<Name>Ice Cream Sandwich</Name>
66+
<Level>15</Level>
67+
<Id>15</Id>
68+
<Stable>True</Stable>
69+
</AndroidApiInfo>
70+
<AndroidApiInfo Include="v4.1">
71+
<Name>Jelly Bean</Name>
72+
<Level>16</Level>
73+
<Id>16</Id>
74+
<Stable>True</Stable>
75+
</AndroidApiInfo>
76+
<AndroidApiInfo Include="v4.2">
77+
<Name>Jelly Bean</Name>
78+
<Level>17</Level>
79+
<Id>17</Id>
80+
<Stable>True</Stable>
81+
</AndroidApiInfo>
82+
<AndroidApiInfo Include="v4.3">
83+
<Name>Jelly Bean</Name>
84+
<Level>18</Level>
85+
<Id>18</Id>
86+
<Stable>True</Stable>
87+
</AndroidApiInfo>
88+
<AndroidApiInfo Include="v4.4">
89+
<Name>Kit Kat</Name>
90+
<Level>19</Level>
91+
<Id>19</Id>
92+
<Stable>True</Stable>
93+
</AndroidApiInfo>
94+
<AndroidApiInfo Include="v4.4.87">
95+
<Name>Kit Kat + Wear support</Name>
96+
<Level>20</Level>
97+
<Id>20</Id>
98+
<Stable>True</Stable>
99+
</AndroidApiInfo>
100+
<AndroidApiInfo Include="v5.0">
101+
<Name>Lollipop</Name>
102+
<Level>21</Level>
103+
<Id>21</Id>
104+
<Stable>True</Stable>
105+
</AndroidApiInfo>
106+
<AndroidApiInfo Include="v5.1">
107+
<Name>Lollipop</Name>
108+
<Level>22</Level>
109+
<Id>22</Id>
110+
<Stable>True</Stable>
111+
</AndroidApiInfo>
112+
<AndroidApiInfo Include="v6.0">
113+
<Name>Marshmallow</Name>
114+
<Level>23</Level>
115+
<Id>23</Id>
116+
<Stable>True</Stable>
117+
</AndroidApiInfo>
118+
<AndroidApiInfo Include="v7.0">
119+
<Name>Nougat</Name>
120+
<Level>24</Level>
121+
<Id>24</Id>
122+
<Stable>True</Stable>
123+
</AndroidApiInfo>
124+
<AndroidApiInfo Include="v7.1">
125+
<Name>Nougat</Name>
126+
<Level>25</Level>
127+
<Id>25</Id>
128+
<Stable>True</Stable>
129+
</AndroidApiInfo>
130+
<AndroidApiInfo Include="v8.0">
131+
<Name>O Preview</Name>
132+
<Level>26</Level>
133+
<Id>O</Id>
134+
<Stable>False</Stable>
135+
</AndroidApiInfo>
136+
</ItemGroup>
137+
</Project>

src/Mono.Android/Mono.Android.targets

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33
<UsingTask AssemblyFile="..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.ReplaceFileContents" />
44
<Import Project="..\..\build-tools\scripts\XAVersionInfo.targets" />
5+
<Import Project="Mono.Android.projitems" />
56
<ItemGroup>
67
<Compile Include="$(IntermediateOutputPath)AssemblyInfo.cs" />
78
</ItemGroup>
@@ -120,6 +121,31 @@
120121
Overwrite="True"
121122
/>
122123
</Target>
124+
<Target Name="_GenerateAndroidApiInfo"
125+
BeforeTargets="_GenerateFrameworkList"
126+
Inputs="$(MSBuildProjectFullPath)"
127+
Outputs="$(OutputPath)AndroidApiInfo.xml">
128+
<MakeDir Directories="$(OutputPath)" />
129+
<ItemGroup>
130+
<_ApiInfo
131+
Condition=" '%(Identity)' == '$(AndroidFrameworkVersion)' "
132+
Include="@(AndroidApiInfo)"
133+
/>
134+
<_Line Include="&lt;AndroidApiInfo&gt;" />
135+
<_Line Include="@(_ApiInfo->' &lt;Id>%(Id)&lt;/Id>')" />
136+
<_Line Include="@(_ApiInfo->' &lt;Level>%(Level)&lt;/Level>')" />
137+
<_Line Include="@(_ApiInfo->' &lt;Name>%(Name)&lt;/Name>')" />
138+
<_Line Include="@(_ApiInfo->' &lt;Version>%(Identity)&lt;/Version>')" />
139+
<_Line Include="@(_ApiInfo->' &lt;Stable>%(Stable)&lt;/Stable>')" />
140+
<_Line Include="&lt;/AndroidApiInfo&gt;" />
141+
</ItemGroup>
142+
<Message Text="# jonp: _Line=@(_Line)" />
143+
<WriteLinesToFile
144+
File="$(OutputPath)AndroidApiInfo.xml"
145+
Lines="@(_Line)"
146+
Overwrite="True"
147+
/>
148+
</Target>
123149
<Target Name="_CleanBinding"
124150
AfterTargets="Clean">
125151
<RemoveDir Directories="$(IntermediateOutputPath)" />

src/Xamarin.Android.Build.Tasks/Tasks/CheckTargetFrameworks.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ int ExtractApiLevel(DirectoryAssemblyResolver res, ITaskItem ass)
3434
var value = p.Value.ToString ();
3535
if (value.StartsWith ("MonoAndroid")) {
3636
var values = value.Split ('=');
37-
return AndroidVersion.TryOSVersionToApiLevel (values[1]);
37+
return MonoDroidSdk.SupportedVersions.GetApiLevelFromFrameworkVersion (values [1]) ?? 0;
3838
}
3939
}
4040
break;
@@ -61,9 +61,9 @@ public override bool Execute ()
6161
}
6262
}
6363

64-
var mainapiLevel = AndroidVersion.TryOSVersionToApiLevel (TargetFrameworkVersion);
64+
var mainapiLevel = MonoDroidSdk.SupportedVersions.GetApiLevelFromFrameworkVersion (TargetFrameworkVersion);
6565
foreach (var item in apiLevels.Where (x => mainapiLevel < x.Value)) {
66-
var itemOSVersion = AndroidVersion.TryApiLevelToOSVersion (item.Value);
66+
var itemOSVersion = MonoDroidSdk.SupportedVersions.GetFrameworkVersionFromApiLevel (item.Value);
6767
Log.LogWarning (null, "XA0105", null, ProjectFile, 0, 0, 0, 0,
6868
"The $(TargetFrameworkVersion) for {0} (v{1}) is greater than the $(TargetFrameworkVersion) for your project ({2}). " +
6969
"You need to increase the $(TargetFrameworkVersion) for your project.", Path.GetFileName (item.Key.ItemSpec), itemOSVersion, TargetFrameworkVersion);

src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.cs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -460,24 +460,18 @@ internal static IEnumerable<string> GetFrameworkAssembliesToTreatAsUserAssemblie
460460
// We may have to use this in the future too.
461461
public static string GetPlatformApiLevelName (string platformApiLevel)
462462
{
463-
switch (platformApiLevel.Trim ()) {
464-
//case "26":
465-
// return "O";
466-
default:
467-
return platformApiLevel;
463+
int apiLevel;
464+
if (int.TryParse (platformApiLevel, out apiLevel)) {
465+
return MonoDroidSdk.SupportedVersions.GetIdFromApiLevel (apiLevel);
468466
}
467+
return platformApiLevel;
469468
}
470469

471470
// It used to replace "21" with "L" when it was preview, or "23" with "MNC" (ditto).
472471
// We may have to use this in the future too.
473472
public static string GetPlatformApiLevel (string platformApiLevelName)
474473
{
475-
switch (platformApiLevelName.Trim ()) {
476-
//case "O":
477-
// return "26";
478-
default:
479-
return platformApiLevelName;
480-
}
474+
return MonoDroidSdk.SupportedVersions.GetApiLevelFromId (platformApiLevelName)?.ToString ();
481475
}
482476

483477
public static Dictionary<string, string> LoadAcwMapFile (string acwPath)

src/Xamarin.Android.Build.Utilities/AndroidAppManifest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public int? TargetSdkVersion {
166166
return null;
167167
int vn;
168168
if (!int.TryParse (version, out vn))
169-
vn = AndroidVersion.MaxApiLevel;
169+
return null;
170170
return vn;
171171
}
172172

src/Xamarin.Android.Build.Utilities/AndroidSdk.cs

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,7 @@ public static void Refresh (string androidSdkPath = null, string androidNdkPath
2020
sdk.Initialize (androidSdkPath ?? sdk.PreferedAndroidSdkPath, androidNdkPath ?? sdk.PreferedAndroidNdkPath,
2121
javaSdkPath ?? sdk.PreferedJavaSdkPath);
2222
if (IsInstalled) {
23-
var levels = GetInstalledPlatformVersions ().Select (l => l.ApiLevel.ToString ()).ToArray ();
24-
string levelList;
25-
if (levels == null || levels.Length == 0)
26-
levelList = "(none)";
27-
else
28-
levelList = string.Join (", ", levels);
29-
AndroidLogger.LogInfo (null, "Found Android SDK. API levels: {0}", levelList);
23+
AndroidLogger.LogInfo (null, "Found Android SDK.");
3024
} else {
3125
AndroidLogger.LogInfo (null, "Did not find Android SDK");
3226
}
@@ -80,13 +74,6 @@ static Version TryParseVersion (string v)
8074
return null;
8175
}
8276

83-
// it was useful when android-21 was android-L, or android-23 was android-MNC.
84-
// We will use this when similar preview release is out.
85-
static string ToApiName (int apiLevel)
86-
{
87-
return apiLevel.ToString ();
88-
}
89-
9077
static string ValidatePath (string path)
9178
{
9279
if (String.IsNullOrEmpty (path))
@@ -96,30 +83,31 @@ static string ValidatePath (string path)
9683

9784
public static string GetPlatformDirectory (int apiLevel)
9885
{
99-
return Path.Combine (AndroidSdkPath, "platforms", "android-" + ToApiName (apiLevel));
86+
return GetPlatformDirectoryFromId (apiLevel.ToString ());
87+
}
88+
89+
public static string GetPlatformDirectoryFromId (string id)
90+
{
91+
return Path.Combine (AndroidSdkPath, "platforms", "android-" + id);
10092
}
10193

10294
public static string GetPlatformDirectory (string osVersion)
10395
{
104-
var level = AndroidVersion.TryOSVersionToApiLevel (osVersion);
105-
if (level == 0)
96+
var id = MonoDroidSdk.SupportedVersions.GetIdFromOSVersion (osVersion);
97+
if (id == null)
10698
return null;
107-
return GetPlatformDirectory (level);
99+
return GetPlatformDirectoryFromId (id);
108100
}
109101

110102
public static bool IsPlatformInstalled (int apiLevel)
111103
{
112104
return apiLevel != 0 && Directory.Exists (GetPlatformDirectory (apiLevel));
113105
}
114106

107+
[Obsolete ("Use MonoDroidSdk.GetInstalledAndroidPlatformVersions")]
115108
public static IEnumerable<AndroidVersion> GetInstalledPlatformVersions ()
116109
{
117-
var knownAndInstalledSdkLevels = AndroidVersion.KnownVersions.Where (v => IsPlatformInstalled (v.ApiLevel));
118-
119-
return knownAndInstalledSdkLevels.Where (version => {
120-
var apiLevel = MonoDroidSdk.GetApiLevelForFrameworkVersion (version.OSVersion);
121-
return MonoDroidSdk.IsSupportedFrameworkLevel (apiLevel);
122-
});
110+
return MonoDroidSdk.GetInstalledAndroidPlatformVersions ();
123111
}
124112

125113
public static bool IsInstalled {

0 commit comments

Comments
 (0)