diff --git a/.gitmodules b/.gitmodules
index 0c3ab256194..7dd76d7ea06 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -29,3 +29,6 @@
path = external/llvm
url = https://github.com/mono/llvm.git
branch = master
+[submodule "external/xamarin-android-tools"]
+ path = external/xamarin-android-tools
+ url = git@github.com:xamarin/xamarin-android-tools.git
diff --git a/Xamarin.Android.sln b/Xamarin.Android.sln
index 03bb4f780aa..f65014728cc 100644
--- a/Xamarin.Android.sln
+++ b/Xamarin.Android.sln
@@ -91,12 +91,16 @@ Project("{9344BDBB-3E7F-41FC-A0DD-8665D75EE146}") = "bundle", "build-tools\bundl
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "xa-prep-tasks", "build-tools\xa-prep-tasks\xa-prep-tasks.csproj", "{7CE69551-BD73-4726-ACAA-AAF89C84BAF8}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Android.Tools", "external\xamarin-android-tools\src\Xamarin.Android.Tools\Xamarin.Android.Tools.csproj", "{E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|AnyCPU = Debug|AnyCPU
Release|AnyCPU = Release|AnyCPU
XAIntegrationDebug|AnyCPU = XAIntegrationDebug|AnyCPU
XAIntegrationRelease|AnyCPU = XAIntegrationRelease|AnyCPU
+ XAIntegrationDebug|Any CPU = XAIntegrationDebug|Any CPU
+ XAIntegrationRelease|Any CPU = XAIntegrationRelease|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3F1F2F50-AF1A-4A5A-BEDB-193372F068D7}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
@@ -417,6 +421,18 @@ Global
{7CE69551-BD73-4726-ACAA-AAF89C84BAF8}.XAIntegrationDebug|AnyCPU.Build.0 = Debug|Any CPU
{7CE69551-BD73-4726-ACAA-AAF89C84BAF8}.XAIntegrationRelease|AnyCPU.ActiveCfg = Debug|Any CPU
{7CE69551-BD73-4726-ACAA-AAF89C84BAF8}.XAIntegrationRelease|AnyCPU.Build.0 = Debug|Any CPU
+ {E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
+ {E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}.Debug|AnyCPU.Build.0 = Debug|Any CPU
+ {E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}.Release|AnyCPU.ActiveCfg = Release|Any CPU
+ {E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}.Release|AnyCPU.Build.0 = Release|Any CPU
+ {E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}.XAIntegrationDebug|AnyCPU.ActiveCfg = Debug|Any CPU
+ {E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}.XAIntegrationDebug|AnyCPU.Build.0 = Debug|Any CPU
+ {E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}.XAIntegrationRelease|AnyCPU.ActiveCfg = Debug|Any CPU
+ {E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}.XAIntegrationRelease|AnyCPU.Build.0 = Debug|Any CPU
+ {E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}.XAIntegrationDebug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}.XAIntegrationDebug|Any CPU.Build.0 = Debug|Any CPU
+ {E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}.XAIntegrationRelease|Any CPU.ActiveCfg = Debug|Any CPU
+ {E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}.XAIntegrationRelease|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{8FF78EB6-6FC8-46A7-8A15-EBBA9045C5FA} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
@@ -460,6 +476,7 @@ Global
{0DE278D6-000F-4001-BB98-187C0AF58A61} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
{1640725C-4DB8-4D8D-BC96-74E688A06EEF} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
{7CE69551-BD73-4726-ACAA-AAF89C84BAF8} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
+ {E34BCFA0-CAA4-412C-AA1C-75DB8D67D157} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0
diff --git a/external/xamarin-android-tools b/external/xamarin-android-tools
new file mode 160000
index 00000000000..641945a90af
--- /dev/null
+++ b/external/xamarin-android-tools
@@ -0,0 +1 @@
+Subproject commit 641945a90af8a4a64b83d6b689c1f3a4fb089ce2
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs
index 1e229aea339..8009d3f0283 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs
@@ -10,6 +10,7 @@
using Java.Interop.Tools.Diagnostics;
using Xamarin.Android.Build.Utilities;
+using Xamarin.Android.Tools;
namespace Xamarin.Android.Tasks
{
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/NdkUtils.cs b/src/Xamarin.Android.Build.Tasks/Tasks/NdkUtils.cs
index 4928b6dfbca..8d0756c8ec9 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/NdkUtils.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/NdkUtils.cs
@@ -11,6 +11,7 @@
using Java.Interop.Tools.Diagnostics;
using Xamarin.Android.Build.Utilities;
+using Xamarin.Android.Tools;
namespace Xamarin.Android.Tasks
{
diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj
index 97caaae9c18..06b9bfd8355 100644
--- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj
+++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj
@@ -643,6 +643,10 @@
{E248B2CA-303B-4645-ADDC-9D4459D550FD}
libZipSharp
+
+ {E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}
+ Xamarin.Android.Tools
+
diff --git a/src/Xamarin.Android.Build.Utilities/AndroidAppManifest.cs b/src/Xamarin.Android.Build.Utilities/AndroidAppManifest.cs
deleted file mode 100644
index d7afc4cabe6..00000000000
--- a/src/Xamarin.Android.Build.Utilities/AndroidAppManifest.cs
+++ /dev/null
@@ -1,314 +0,0 @@
-using System;
-using System.Linq;
-using System.Xml;
-using System.Collections.Generic;
-using System.Xml.Linq;
-using System.Text.RegularExpressions;
-using System.Text;
-using System.IO;
-
-namespace Xamarin.Android.Build.Utilities
-{
- public class AndroidAppManifest
- {
- XDocument doc;
- XElement manifest, application, usesSdk;
-
- static readonly XNamespace aNS = "http://schemas.android.com/apk/res/android";
- static readonly XName aName = aNS + "name";
-
- AndroidAppManifest (XDocument doc)
- {
- this.doc = doc;
- manifest = doc.Root;
- if (manifest.Name != "manifest")
- throw new Exception ("App manifest does not have 'manifest' root element");
-
- application = manifest.Element ("application");
- if (application == null)
- manifest.Add (application = new XElement ("application"));
-
- usesSdk = manifest.Element ("uses-sdk");
- if (usesSdk == null)
- manifest.Add (usesSdk = new XElement ("uses-sdk"));
- }
-
- public static string CanonicalizePackageName (string packageNameOrAssemblyName)
- {
- if (packageNameOrAssemblyName == null)
- throw new ArgumentNullException ("packageNameOrAssemblyName");
- if (string.IsNullOrEmpty (packageNameOrAssemblyName = packageNameOrAssemblyName.Trim ()))
- throw new ArgumentException ("Must specify a package name or assembly name", "packageNameOrAssemblyName");
-
- string[] packageParts = packageNameOrAssemblyName.Split (new[]{'.'}, StringSplitOptions.RemoveEmptyEntries);
- for (int i = 0; i < packageParts.Length; ++i) {
- packageParts [i] = Regex.Replace (packageParts [i], "[^A-Za-z0-9_]", "_");
- if (char.IsDigit (packageParts [i], 0) || packageParts [i][0] == '_')
- packageParts [i] = "x" + packageParts [i];
- }
- return packageParts.Length == 1
- ? packageParts [0] + "." + packageParts [0]
- : string.Join (".", packageParts);
- }
-
- public static AndroidAppManifest Create (string packageName, string appLabel)
- {
- return new AndroidAppManifest (XDocument.Parse (
- @"
-
-
-
-
-")) {
- PackageName = packageName,
- ApplicationLabel = appLabel,
- };
- }
-
- public static AndroidAppManifest Load (string filename)
- {
- return Load (XDocument.Load (filename));
- }
-
- public static AndroidAppManifest Load (XDocument doc)
- {
- return new AndroidAppManifest (doc);
- }
-
- public void Write (XmlWriter writer)
- {
- doc.Save (writer);
- }
-
- public void WriteToFile (string fileName)
- {
- var xmlSettings = new XmlWriterSettings () {
- Encoding = Encoding.UTF8,
- CloseOutput = false,
- Indent = true,
- IndentChars = "\t",
- NewLineChars = "\n",
- };
-
- var tempFile = FileUtil.GetTempFilenameForWrite (fileName);
- bool success = false;
- try {
- using (var writer = XmlTextWriter.Create (tempFile, xmlSettings)) {
- Write (writer);
- }
- FileUtil.SystemRename (tempFile, fileName);
- success = true;
- } finally {
- if (!success) {
- try {
- File.Delete (tempFile);
- } catch {
- //the original exception is more important than this one
- }
- }
- }
- }
-
- static string NullIfEmpty (string value)
- {
- return string.IsNullOrEmpty (value) ? null : value;
- }
-
- public string PackageName {
- get { return (string) manifest.Attribute ("package"); }
- set { manifest.SetAttributeValue ("package", NullIfEmpty (value)); }
- }
-
- public string ApplicationLabel {
- get { return (string) application.Attribute (aNS + "label"); }
- set { application.SetAttributeValue (aNS + "label", NullIfEmpty (value)); }
- }
-
- public string ApplicationIcon {
- get { return (string) application.Attribute (aNS + "icon"); }
- set { application.SetAttributeValue (aNS + "icon", NullIfEmpty (value)); }
- }
-
- public string ApplicationTheme {
- get { return (string) application.Attribute (aNS + "theme"); }
- set { application.SetAttributeValue (aNS + "theme", NullIfEmpty (value)); }
- }
-
- public string VersionName {
- get { return (string) manifest.Attribute (aNS + "versionName"); }
- set { manifest.SetAttributeValue (aNS + "versionName", NullIfEmpty (value)); }
- }
-
- public string VersionCode {
- get { return (string) manifest.Attribute (aNS + "versionCode"); }
- set { manifest.SetAttributeValue (aNS + "versionCode", NullIfEmpty (value)); }
- }
-
- public string InstallLocation {
- get { return (string) manifest.Attribute (aNS + "installLocation"); }
- set { manifest.SetAttributeValue (aNS + "installLocation", NullIfEmpty (value)); }
- }
-
- public int? MinSdkVersion {
- get { return ParseSdkVersion (usesSdk.Attribute (aNS + "minSdkVersion")); }
- set { usesSdk.SetAttributeValue (aNS + "minSdkVersion", value == null ? null : value.ToString ()); }
- }
-
- public int? TargetSdkVersion {
- get { return ParseSdkVersion (usesSdk.Attribute (aNS + "targetSdkVersion")); }
- set { usesSdk.SetAttributeValue (aNS + "targetSdkVersion", value == null ? null : value.ToString ()); }
- }
-
- int? ParseSdkVersion (XAttribute attribute)
- {
- var version = (string)attribute;
- if (string.IsNullOrEmpty (version))
- return null;
- int vn;
- if (!int.TryParse (version, out vn))
- vn = AndroidVersion.MaxApiLevel;
- return vn;
- }
-
- public IEnumerable AndroidPermissions {
- get {
- foreach (var el in manifest.Elements ("uses-permission")) {
- var name = (string) el.Attribute (aName);
- if (name == null)
- continue;
- var lastDot = name.LastIndexOf ('.');
- if (lastDot >= 0)
- yield return name.Substring (lastDot + 1);
- }
- }
- }
-
- public IEnumerable AndroidPermissionsQualified {
- get {
- foreach (var el in manifest.Elements ("uses-permission")) {
- var name = (string) el.Attribute (aName);
- if (name != null)
- yield return name;
- }
- }
- }
-
- public bool? Debuggable {
- get { return (bool?) application.Attribute (aNS + "debuggable"); }
- set { application.SetAttributeValue (aNS + "debuggable", value); }
- }
-
- public void SetAndroidPermissions (IEnumerable permissions)
- {
- var newPerms = new HashSet (permissions.Select (FullyQualifyPermission));
- var current = new HashSet (AndroidPermissionsQualified);
- AddAndroidPermissions (newPerms.Except (current));
- RemoveAndroidPermissions (current.Except (newPerms));
- }
-
- void AddAndroidPermissions (IEnumerable permissions)
- {
- var newElements = permissions.Select (p => new XElement ("uses-permission", new XAttribute (aName, p)));
-
- var lastPerm = manifest.Elements ("uses-permission").LastOrDefault ();
- if (lastPerm != null) {
- foreach (var el in newElements) {
- lastPerm.AddAfterSelf (el);
- lastPerm = el;
- }
- } else {
- var parentNode = (XNode) manifest.Element ("application") ?? manifest.LastNode;
- foreach (var el in newElements)
- parentNode.AddBeforeSelf (el);
- }
- }
-
- string FullyQualifyPermission (string permission)
- {
- //if already qualified, don't mess with it
- if (permission.IndexOf ('.') > -1)
- return permission;
-
- switch (permission) {
- case "READ_HISTORY_BOOKMARKS":
- case "WRITE_HISTORY_BOOKMARKS":
- return string.Format ("com.android.browser.permission.{0}", permission);
- default:
- return string.Format ("android.permission.{0}", permission);
- }
- }
-
- void RemoveAndroidPermissions (IEnumerable permissions)
- {
- var perms = new HashSet (permissions);
- var list = manifest.Elements ("uses-permission")
- .Where (el => perms.Contains ((string)el.Attribute (aName))).ToList ();
- foreach (var el in list)
- el.Remove ();
- }
-
- [Obsolete ("Use GetLaunchableFastdevActivityName or GetLaunchableUserActivityName")]
- public string GetLaunchableActivityName ()
- {
- return GetLaunchableFastDevActivityName ();
- }
-
- /// Gets an activity that can be used to initialize the override directory for fastdev.
- [Obsolete ("This should not be needed anymore; Activity execution is not part of installation.")]
- public string GetLaunchableFastDevActivityName ()
- {
- string first = null;
- foreach (var a in GetLaunchableActivities ()) {
- var name = (string) a.Attribute (aName);
- //prefer the fastdev launcher, it's quicker
- if (name == "mono.android.__FastDevLauncher") {
- return name;
- }
- //else just use the first other launchable activity
- if (first == null) {
- first = name;
- }
- }
-
- return string.IsNullOrEmpty (first)? null : first;
- }
-
- // We add a fake launchable activity for FastDev, but we don't want
- // to launch that one when the user does Run or Debug
- public string GetLaunchableUserActivityName ()
- {
- return GetLaunchableActivities ()
- .Select (a => (string) a.Attribute (aName))
- .FirstOrDefault (name => !string.IsNullOrEmpty (name) && name != "mono.android.__FastDevLauncher");
- }
-
- IEnumerable GetLaunchableActivities ()
- {
- foreach (var activity in application.Elements ("activity")) {
- var filter = activity.Element ("intent-filter");
- if (filter != null) {
- foreach (var category in filter.Elements ("category"))
- if (category != null && (string)category.Attribute (aName) == "android.intent.category.LAUNCHER")
- yield return activity;
- }
- }
- }
-
- public IEnumerable GetAllActivityNames ()
- {
- foreach (var activity in application.Elements ("activity")) {
- var activityName = (string) activity.Attribute (aName);
- if (activityName != "mono.android.__FastDevLauncher")
- yield return activityName;
- }
- }
-
- public IEnumerable GetLaunchableActivityNames ()
- {
- return GetLaunchableActivities ()
- .Select (a => (string) a.Attribute (aName))
- .Where (name => !string.IsNullOrEmpty (name) && name != "mono.android.__FastDevLauncher");
- }
- }
-}
-
diff --git a/src/Xamarin.Android.Build.Utilities/AndroidLogger.cs b/src/Xamarin.Android.Build.Utilities/AndroidLogger.cs
deleted file mode 100644
index d06a0109ac4..00000000000
--- a/src/Xamarin.Android.Build.Utilities/AndroidLogger.cs
+++ /dev/null
@@ -1,129 +0,0 @@
-using System;
-
-namespace Xamarin.Android.Build.Utilities
-{
- public delegate void MessageHandler (string task, string message);
- public delegate void TaskLogHandler (AndroidTaskLog log);
-
- public static class AndroidLogger
- {
- public static event MessageHandler Info;
- public static event MessageHandler Warning;
- public static event MessageHandler Error;
- public static event MessageHandler Debug;
- public static event TaskLogHandler Task;
-
- public static void LogInfo (string format, params object[] args)
- {
- LogInfo (string.Empty, format, args);
- }
-
- public static void LogInfo (string task, string format, params object[] args)
- {
- if (Info != null) {
- if (args == null || args.Length == 0)
- Info (task, format);
- else
- Info (task, String.Format (format, args));
- } else
- throw new InvalidOperationException ("Internal Error: should initialize Info");
- }
-
- public static void LogWarning (string format, params object[] args)
- {
- LogWarning (string.Empty, format, args);
- }
-
- public static void LogWarning (string task, string format, params object[] args)
- {
- if (Warning != null) {
- if (args == null)
- Warning (task, format);
- else
- Warning (task, String.Format (format, args));
- } else
- throw new InvalidOperationException ("Internal Error: should initialize Warning");
- }
-
- public static void LogError (string format, params object[] args)
- {
- LogError (string.Empty, format, args);
- }
-
- public static void LogError (string message, Exception ex)
- {
- message += (ex != null? System.Environment.NewLine + ex.ToString () : string.Empty);
- LogError (message);
- }
-
- public static void LogError (string task, string format, params object[] args)
- {
- if (Error != null) {
- if (args == null || args.Length == 0)
- Error (task, format);
- else
- Error (task, String.Format (format, args));
- } else
- throw new InvalidOperationException ("Internal Error: should initialize Error");
- }
-
- public static void LogDebug (string format, params object[] args)
- {
- LogDebug (string.Empty, format, args);
- }
-
- public static void LogDebug (string task, string format, params object[] args)
- {
- if (Debug != null) {
- if (args == null || args.Length == 0)
- Debug (task, format);
- else
- Debug (task, String.Format (format, args));
- } else
- throw new InvalidOperationException ("Internal Error: should initialize Debug");
- }
-
- public static void LogTask (AndroidTaskLog log)
- {
- if (Task != null)
- Task (log);
- else
- throw new InvalidOperationException ("Internal Error: should initialize Task");
- }
- }
-
- public class AndroidTaskLog
- {
- public string Task { get; private set; }
- public string Input { get; private set; }
- public string Output { get; private set; }
- public DateTime StartTime { get; private set; }
- public DateTime EndTime { get; private set; }
-
- public AndroidTaskLog (string task, string input)
- {
- Task = task;
- Input = input;
- StartTime = DateTime.Now;
- }
-
- public AndroidTaskLog Complete (string output)
- {
- Output = output;
- EndTime = DateTime.Now;
-
- return this;
- }
-
- public AndroidTaskLog Complete (object output)
- {
- if (output == null)
- output = "";
- Output = output.ToString();
- EndTime = DateTime.Now;
-
- return this;
- }
- }
-}
-
diff --git a/src/Xamarin.Android.Build.Utilities/AndroidSdk.cs b/src/Xamarin.Android.Build.Utilities/AndroidSdk.cs
deleted file mode 100644
index 11b81559af5..00000000000
--- a/src/Xamarin.Android.Build.Utilities/AndroidSdk.cs
+++ /dev/null
@@ -1,148 +0,0 @@
-using System;
-using System.Linq;
-using System.Collections.Generic;
-using System.IO;
-
-namespace Xamarin.Android.Build.Utilities
-{
- public class AndroidSdk
- {
- private static AndroidSdkBase sdk;
-
- public static void Refresh (string androidSdkPath = null, string androidNdkPath = null, string javaSdkPath = null)
- {
- if (OS.IsWindows)
- sdk = new AndroidSdkWindows ();
- else
- sdk = new AndroidSdkUnix ();
-
- try {
- sdk.Initialize (androidSdkPath ?? sdk.PreferedAndroidSdkPath, androidNdkPath ?? sdk.PreferedAndroidNdkPath,
- javaSdkPath ?? sdk.PreferedJavaSdkPath);
- if (IsInstalled) {
- var levels = GetInstalledPlatformVersions ().Select (l => l.ApiLevel.ToString ()).ToArray ();
- string levelList;
- if (levels == null || levels.Length == 0)
- levelList = "(none)";
- else
- levelList = string.Join (", ", levels);
- AndroidLogger.LogInfo (null, "Found Android SDK. API levels: {0}", levelList);
- } else {
- AndroidLogger.LogInfo (null, "Did not find Android SDK");
- }
- } catch (Exception ex) {
- AndroidLogger.LogError ("Error finding Android/Java SDKs", ex);
- }
- }
-
- public static IEnumerable GetBuildToolsPaths (string preferredBuildToolsVersion)
- {
- if (!string.IsNullOrEmpty (preferredBuildToolsVersion)) {
- var preferredDir = Path.Combine (AndroidSdkPath, "build-tools", preferredBuildToolsVersion);
- if (Directory.Exists (preferredDir))
- return new[] { preferredDir }.Concat (GetBuildToolsPaths ().Where (p => p!= preferredDir));
- }
- return GetBuildToolsPaths ();
- }
-
- public static IEnumerable GetBuildToolsPaths ()
- {
- ValidatePath (AndroidSdkPath);
-
- var buildTools = Path.Combine (AndroidSdkPath, "build-tools");
- if (Directory.Exists (buildTools)) {
- var preview = Directory.EnumerateDirectories (buildTools)
- .Where(x => TryParseVersion (Path.GetFileName (x)) == null)
- .Select(x => x);
-
- foreach (var d in preview)
- yield return d;
-
- var sorted = from p in Directory.EnumerateDirectories (buildTools)
- let version = TryParseVersion (Path.GetFileName (p))
- where version != null
- orderby version descending
- select p;
-
- foreach (var d in sorted)
- yield return d;
- }
- var ptPath = Path.Combine (AndroidSdkPath, "platform-tools");
- if (Directory.Exists (ptPath))
- yield return ptPath;
- }
-
- static Version TryParseVersion (string v)
- {
- Version version;
- if (Version.TryParse (v, out version))
- return version;
- return null;
- }
-
- // it was useful when android-21 was android-L, or android-23 was android-MNC.
- // We will use this when similar preview release is out.
- static string ToApiName (int apiLevel)
- {
- return apiLevel.ToString ();
- }
-
- static string ValidatePath (string path)
- {
- if (String.IsNullOrEmpty (path))
- throw new InvalidOperationException ("This property is not valid when the SDK is not installed");
- return path;
- }
-
- public static string GetPlatformDirectory (int apiLevel)
- {
- return Path.Combine (AndroidSdkPath, "platforms", "android-" + ToApiName (apiLevel));
- }
-
- public static string GetPlatformDirectory (string osVersion)
- {
- var level = AndroidVersion.TryOSVersionToApiLevel (osVersion);
- if (level == 0)
- return null;
- return GetPlatformDirectory (level);
- }
-
- public static bool IsPlatformInstalled (int apiLevel)
- {
- return apiLevel != 0 && Directory.Exists (GetPlatformDirectory (apiLevel));
- }
-
- public static IEnumerable GetInstalledPlatformVersions ()
- {
- var knownAndInstalledSdkLevels = AndroidVersion.KnownVersions.Where (v => IsPlatformInstalled (v.ApiLevel));
-
- return knownAndInstalledSdkLevels.Where (version => {
- var apiLevel = MonoDroidSdk.GetApiLevelForFrameworkVersion (version.OSVersion);
- return MonoDroidSdk.IsSupportedFrameworkLevel (apiLevel);
- });
- }
-
- public static bool IsInstalled {
- get {
- return !string.IsNullOrEmpty (AndroidSdkPath) && !string.IsNullOrEmpty (JavaSdkPath);
- }
- }
-
- public static string AndroidNdkPath {
- get { return sdk.AndroidNdkPath; }
- }
-
- public static string AndroidSdkPath {
- get { return sdk.AndroidSdkPath; }
- }
-
- public static string JavaSdkPath {
- get { return sdk.JavaSdkPath; }
- }
-
- public static string AndroidNdkHostPlatform {
- get { return sdk.NdkHostPlatform; }
- }
- }
-}
-
diff --git a/src/Xamarin.Android.Build.Utilities/AndroidTargetArch.cs b/src/Xamarin.Android.Build.Utilities/AndroidTargetArch.cs
deleted file mode 100644
index 7aebeee6fd8..00000000000
--- a/src/Xamarin.Android.Build.Utilities/AndroidTargetArch.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System;
-using System.Text.RegularExpressions;
-using System.IO;
-
-namespace Xamarin.Android.Build.Utilities
-{
- [Flags]
- public enum AndroidTargetArch
- {
- None = 0,
- Arm = 1,
- X86 = 2,
- Mips = 4,
- Arm64 = 8,
- X86_64 = 16,
- Other = 0x10000 // hope it's not too optimistic
- }
-}
-
diff --git a/src/Xamarin.Android.Build.Utilities/AndroidVersion.cs b/src/Xamarin.Android.Build.Utilities/AndroidVersion.cs
deleted file mode 100644
index a9803722dbb..00000000000
--- a/src/Xamarin.Android.Build.Utilities/AndroidVersion.cs
+++ /dev/null
@@ -1,108 +0,0 @@
-using System;
-
-namespace Xamarin.Android.Build.Utilities
-{
- public class AndroidVersion
- {
- public static readonly int MaxApiLevel = 24;
-
- public AndroidVersion (int apilevel, string osVersion)
- {
- this.ApiLevel = apilevel;
- this.OSVersion = osVersion;
- }
-
- AndroidVersion (int apilevel, string osVersion, string codeName, Version version)
- {
- this.ApiLevel = apilevel;
- // TODO: remove osVersion from parameter list and generate from version
- this.OSVersion = osVersion;
- this.CodeName = codeName;
- this.Version = version;
- }
-
- public int ApiLevel { get; private set; }
- public string OSVersion { get; private set; }
- public string CodeName { get; private set; }
- public Version Version { get; private set; }
-
- public static int OSVersionToApiLevel (string osVersion)
- {
- int ret = TryOSVersionToApiLevel (osVersion);
- if (ret == 0)
- throw new ArgumentOutOfRangeException ("OS version not recognized: " + osVersion);
- return ret;
- }
-
- public static int TryOSVersionToApiLevel (string frameworkVersion)
- {
- // Use MonoDroidSdk.GetApiLevelForFrameworkVersion because that will translate XA versions >= 5.xx to the correct api level
- var apiLevelText = MonoDroidSdk.GetApiLevelForFrameworkVersion (frameworkVersion);
- int apiLevel;
- int.TryParse (apiLevelText, out apiLevel);
- return apiLevel;
- }
-
- public static string ApiLevelToOSVersion (int apiLevel)
- {
- string ret = TryApiLevelToOSVersion (apiLevel);
- if (ret == null)
- throw new ArgumentOutOfRangeException ("API level not recognized: " + apiLevel);
- return ret;
- }
-
- public static string TryApiLevelToOSVersion (int apiLevel)
- {
- var osVersion = MonoDroidSdk.GetFrameworkVersionForApiLevel (apiLevel.ToString ());
- if (!string.IsNullOrEmpty (osVersion))
- return osVersion.TrimStart ('v');
- return null;
- }
-
- public static string TryOSVersionToCodeName (string frameworkVersion)
- {
- // match on API level, the framework version might not match what we have here (>= XA 5.x uses a different version scheme)
- var apiLevel = TryOSVersionToApiLevel (frameworkVersion);
-
- foreach (AndroidVersion version in KnownVersions)
- if (version.ApiLevel == apiLevel)
- return version.CodeName;
- return null;
- }
-
- public static string TryFrameworkVersionToOSVersion (string frameworkVersion)
- {
- // match on API level, the framework version might not match what we have here (>= XA 5.x uses a different version scheme)
- var apiLevel = TryOSVersionToApiLevel (frameworkVersion);
-
- foreach (AndroidVersion version in KnownVersions)
- if (version.ApiLevel == apiLevel)
- return version.OSVersion;
- return null;
- }
-
- public static AndroidVersion[] KnownVersions = new[] {
- new AndroidVersion (4, "1.6", "Donut", new Version (1, 6)),
- new AndroidVersion (5, "2.0", "Eclair", new Version (2, 0)),
- new AndroidVersion (6, "2.0.1", "Eclair", new Version (2, 0, 1)),
- new AndroidVersion (7, "2.1", "Eclair", new Version (2, 1)),
- new AndroidVersion (8, "2.2", "Froyo", new Version (2, 2)),
- new AndroidVersion (10, "2.3", "Gingerbread", new Version (2, 3)),
- new AndroidVersion (11, "3.0", "Honeycomb", new Version (3, 0)),
- new AndroidVersion (12, "3.1", "Honeycomb", new Version (3, 1)),
- new AndroidVersion (13, "3.2", "Honeycomb", new Version (3, 2)),
- new AndroidVersion (14, "4.0", "Ice Cream Sandwich", new Version (4, 0)),
- new AndroidVersion (15, "4.0.3", "Ice Cream Sandwich", new Version (4, 0, 3)),
- new AndroidVersion (16, "4.1", "Jelly Bean", new Version (4, 1)),
- new AndroidVersion (17, "4.2", "Jelly Bean", new Version (4, 2)),
- new AndroidVersion (18, "4.3", "Jelly Bean", new Version (4, 3)),
- new AndroidVersion (19, "4.4", "Kit Kat", new Version (4, 4)),
- new AndroidVersion (20, "4.4.87", "Kit Kat + Wear support", new Version (4, 4, 87)),
- new AndroidVersion (21, "5.0", "Lollipop", new Version (5, 0)),
- new AndroidVersion (22, "5.1", "Lollipop", new Version (5, 1)),
- new AndroidVersion (23, "6.0", "Marshmallow", new Version (6, 0)),
- new AndroidVersion (24, "7.0", "Nougat", new Version (7, 0)),
- };
- }
-}
-
diff --git a/src/Xamarin.Android.Build.Utilities/FileUtil.cs b/src/Xamarin.Android.Build.Utilities/FileUtil.cs
index 7c81d7e4ad0..c7de9112884 100644
--- a/src/Xamarin.Android.Build.Utilities/FileUtil.cs
+++ b/src/Xamarin.Android.Build.Utilities/FileUtil.cs
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
+using Xamarin.Android.Tools;
namespace Xamarin.Android.Build.Utilities
{
diff --git a/src/Xamarin.Android.Build.Utilities/GdbPaths.cs b/src/Xamarin.Android.Build.Utilities/GdbPaths.cs
index e4079fc4765..97c22748547 100644
--- a/src/Xamarin.Android.Build.Utilities/GdbPaths.cs
+++ b/src/Xamarin.Android.Build.Utilities/GdbPaths.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using Xamarin.Android.Tools;
namespace Xamarin.Android.Build.Utilities
{
diff --git a/src/Xamarin.Android.Build.Utilities/MonoDroidSdk.cs b/src/Xamarin.Android.Build.Utilities/MonoDroidSdk.cs
deleted file mode 100644
index 9781e40a755..00000000000
--- a/src/Xamarin.Android.Build.Utilities/MonoDroidSdk.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using System;
-using System.IO;
-
-namespace Xamarin.Android.Build.Utilities
-{
- public static class MonoDroidSdk
- {
- static MonoDroidSdkBase sdk;
-
- public static string GetApiLevelForFrameworkVersion (string framework)
- {
- return GetSdk ().GetApiLevelForFrameworkVersion (framework);
- }
-
- public static string GetFrameworkVersionForApiLevel (string apiLevel)
- {
- return GetSdk ().GetFrameworkVersionForApiLevel (apiLevel);
- }
-
- public static bool IsSupportedFrameworkLevel (string apiLevel)
- {
- return GetSdk ().IsSupportedFrameworkLevel (apiLevel);
- }
-
- public static void Refresh (string runtimePath = null, string binPath = null, string bclPath = null)
- {
- if (OS.IsWindows) {
- sdk = new MonoDroidSdkWindows ();
- } else {
- sdk = new MonoDroidSdkUnix ();
- }
-
- try {
- sdk.Initialize (runtimePath, binPath, bclPath);
- } catch (Exception ex) {
- AndroidLogger.LogError ("Error finding Xamarin.Android SDK", ex);
- }
- }
-
- static MonoDroidSdkBase GetSdk ()
- {
- if (sdk == null) {
- Refresh ();
- }
- return sdk;
- }
-
- public static string RuntimePath { get { return GetSdk ().RuntimePath; } }
-
- public static string BinPath { get { return GetSdk ().BinPath; } }
-
- public static string FrameworkPath { get { return GetSdk ().BclPath; } }
-
- [Obsolete ("Do not use.")]
- public static string JavaDocToMDocExe {
- get { return Path.Combine (BinPath, OS.IsWindows ? "javadoc-to-mdoc.exe" : "javadoc-to-mdoc"); }
- }
- }
-}
-
diff --git a/src/Xamarin.Android.Build.Utilities/OS.cs b/src/Xamarin.Android.Build.Utilities/OS.cs
deleted file mode 100644
index 0ff07cd2185..00000000000
--- a/src/Xamarin.Android.Build.Utilities/OS.cs
+++ /dev/null
@@ -1,227 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-using System.IO;
-using System.Text;
-
-namespace Xamarin.Android.Build.Utilities
-{
- public class OS
- {
- public readonly static bool IsWindows;
- public readonly static bool IsMac;
-
- internal readonly static string ProgramFilesX86;
-
- static OS ()
- {
- IsWindows = Path.DirectorySeparatorChar == '\\';
- IsMac = !IsWindows && IsRunningOnMac ();
-
- if (IsWindows) {
- ProgramFilesX86 = GetProgramFilesX86 ();
- }
- }
-
- //From Managed.Windows.Forms/XplatUI
- static bool IsRunningOnMac ()
- {
- IntPtr buf = IntPtr.Zero;
- try {
- buf = Marshal.AllocHGlobal (8192);
- // This is a hacktastic way of getting sysname from uname ()
- if (uname (buf) == 0) {
- string os = System.Runtime.InteropServices.Marshal.PtrToStringAnsi (buf);
- if (os == "Darwin")
- return true;
- }
- } catch {
- } finally {
- if (buf != IntPtr.Zero)
- System.Runtime.InteropServices.Marshal.FreeHGlobal (buf);
- }
- return false;
- }
-
- [DllImport ("libc")]
- static extern int uname (IntPtr buf);
-
- static string GetProgramFilesX86 ()
- {
- //SpecialFolder.ProgramFilesX86 is broken on 32-bit WinXP
- if (IntPtr.Size == 8) {
- return Environment.GetFolderPath (Environment.SpecialFolder.ProgramFilesX86);
- } else {
- return Environment.GetFolderPath (Environment.SpecialFolder.ProgramFiles);
- }
- }
-
- internal static string GetXamarinAndroidCacheDir ()
- {
- if (IsMac) {
- var home = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
- return Path.Combine (home, "Library", "Caches", "Xamarin.Android");
- } else if (IsWindows) {
- var localAppData = Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData);
- return Path.Combine (localAppData, "Xamarin.Android", "Cache");
- } else {
- var home = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
- var xdgCacheHome = Environment.GetEnvironmentVariable ("XDG_CACHE_HOME");
- if (string.IsNullOrEmpty (xdgCacheHome)) {
- xdgCacheHome = Path.Combine (home, ".cache");
- }
- return Path.Combine (xdgCacheHome, "Xamarin.Android");
- }
- }
- }
-
- public static class KernelEx {
- [DllImport ("kernel32.dll", CharSet = CharSet.Auto)]
- static extern int GetLongPathName (
- [MarshalAs (UnmanagedType.LPTStr)] string path,
- [MarshalAs (UnmanagedType.LPTStr)] StringBuilder longPath,
- int longPathLength
- );
-
- public static string GetLongPathName (string path)
- {
- StringBuilder sb = new StringBuilder (255);
- GetLongPathName (path, sb, sb.Capacity);
- return sb.ToString ();
- }
-
- [DllImport ("kernel32.dll", CharSet = CharSet.Auto)]
- static extern int GetShortPathName (
- [MarshalAs (UnmanagedType.LPTStr)] string path,
- [MarshalAs (UnmanagedType.LPTStr)] StringBuilder shortPath,
- int shortPathLength
- );
-
- public static string GetShortPathName (string path)
- {
- StringBuilder sb = new StringBuilder (255);
- GetShortPathName (path, sb, sb.Capacity);
- return sb.ToString ();
- }
- }
-
- internal static class RegistryEx
- {
- const string ADVAPI = "advapi32.dll";
-
- public static UIntPtr CurrentUser = (UIntPtr)0x80000001;
- public static UIntPtr LocalMachine = (UIntPtr)0x80000002;
-
- [DllImport (ADVAPI, CharSet = CharSet.Unicode, SetLastError = true)]
- static extern int RegOpenKeyEx (UIntPtr hKey, string subKey, uint reserved, uint sam, out UIntPtr phkResult);
-
- [DllImport (ADVAPI, CharSet = CharSet.Unicode, SetLastError = true)]
- static extern int RegQueryValueExW (UIntPtr hKey, string lpValueName, int lpReserved, out uint lpType,
- StringBuilder lpData, ref uint lpcbData);
-
- [DllImport (ADVAPI, CharSet = CharSet.Unicode, SetLastError = true)]
- static extern int RegSetValueExW (UIntPtr hKey, string lpValueName, int lpReserved,
- uint dwType, string data, uint cbData);
-
- [DllImport (ADVAPI, CharSet = CharSet.Unicode, SetLastError = true)]
- static extern int RegSetValueExW (UIntPtr hKey, string lpValueName, int lpReserved,
- uint dwType, IntPtr data, uint cbData);
-
- [DllImport (ADVAPI, CharSet = CharSet.Unicode, SetLastError = true)]
- static extern int RegCreateKeyEx (UIntPtr hKey, string subKey, uint reserved, string @class, uint options,
- uint samDesired, IntPtr lpSecurityAttributes, out UIntPtr phkResult, out Disposition lpdwDisposition);
-
- [DllImport ("advapi32.dll", SetLastError = true)]
- static extern int RegCloseKey (UIntPtr hKey);
-
- public static string GetValueString (UIntPtr key, string subkey, string valueName, Wow64 wow64)
- {
- UIntPtr regKeyHandle;
- uint sam = (uint)Rights.QueryValue + (uint)wow64;
- if (RegOpenKeyEx (key, subkey, 0, sam, out regKeyHandle) != 0)
- return null;
-
- try {
- uint type;
- var sb = new StringBuilder (2048);
- uint cbData = (uint) sb.Capacity;
- if (RegQueryValueExW (regKeyHandle, valueName, 0, out type, sb, ref cbData) == 0) {
- return sb.ToString ();
- }
- return null;
- } finally {
- RegCloseKey (regKeyHandle);
- }
- }
-
- public static void SetValueString (UIntPtr key, string subkey, string valueName, string value, Wow64 wow64)
- {
- UIntPtr regKeyHandle;
- uint sam = (uint)(Rights.CreateSubKey | Rights.SetValue) + (uint)wow64;
- uint options = (uint) Options.NonVolatile;
- Disposition disposition;
- if (RegCreateKeyEx (key, subkey, 0, null, options, sam, IntPtr.Zero, out regKeyHandle, out disposition) != 0) {
- throw new Exception ("Could not open or craete key");
- }
-
- try {
- uint type = (uint)ValueType.String;
- uint lenBytesPlusNull = ((uint)value.Length + 1) * 2;
- var result = RegSetValueExW (regKeyHandle, valueName, 0, type, value, lenBytesPlusNull);
- if (result != 0)
- throw new Exception (string.Format ("Error {0} setting registry key '{1}{2}@{3}'='{4}'",
- result, key, subkey, valueName, value));
- } finally {
- RegCloseKey (regKeyHandle);
- }
- }
-
- [Flags]
- enum Rights : uint
- {
- None = 0,
- QueryValue = 0x0001,
- SetValue = 0x0002,
- CreateSubKey = 0x0004,
- EnumerateSubKey = 0x0008,
- }
-
- enum Options
- {
- BackupRestore = 0x00000004,
- CreateLink = 0x00000002,
- NonVolatile = 0x00000000,
- Volatile = 0x00000001,
- }
-
- public enum Wow64 : uint
- {
- Key64 = 0x0100,
- Key32 = 0x0200,
- }
-
- enum ValueType : uint
- {
- None = 0, //REG_NONE
- String = 1, //REG_SZ
- UnexpandedString = 2, //REG_EXPAND_SZ
- Binary = 3, //REG_BINARY
- DWord = 4, //REG_DWORD
- DWordLittleEndian = 4, //REG_DWORD_LITTLE_ENDIAN
- DWordBigEndian = 5, //REG_DWORD_BIG_ENDIAN
- Link = 6, //REG_LINK
- MultiString = 7, //REG_MULTI_SZ
- ResourceList = 8, //REG_RESOURCE_LIST
- FullResourceDescriptor = 9, //REG_FULL_RESOURCE_DESCRIPTOR
- ResourceRequirementsList = 10, //REG_RESOURCE_REQUIREMENTS_LIST
- QWord = 11, //REG_QWORD
- QWordLittleEndian = 11, //REG_QWORD_LITTLE_ENDIAN
- }
-
- enum Disposition : uint
- {
- CreatedNewKey = 0x00000001,
- OpenedExistingKey = 0x00000002,
- }
- }
-}
-
diff --git a/src/Xamarin.Android.Build.Utilities/ProcessUtils.cs b/src/Xamarin.Android.Build.Utilities/ProcessUtils.cs
deleted file mode 100644
index cded992fb84..00000000000
--- a/src/Xamarin.Android.Build.Utilities/ProcessUtils.cs
+++ /dev/null
@@ -1,124 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Threading.Tasks;
-using System.IO;
-using System.Threading;
-
-namespace Xamarin.Android.Build.Utilities
-{
- public static class ProcessUtils
- {
- public static async Task StartProcess (ProcessStartInfo psi, TextWriter stdout, TextWriter stderr, CancellationToken cancellationToken, Action onStarted = null)
- {
- cancellationToken.ThrowIfCancellationRequested ();
- psi.UseShellExecute = false;
- psi.RedirectStandardOutput |= stdout != null;
- psi.RedirectStandardError |= stderr != null;
-
- var process = new Process {
- StartInfo = psi,
- EnableRaisingEvents = true,
- };
-
- Task output = Task.FromResult (true);
- Task error = Task.FromResult (true);
- Task exit = WaitForExitAsync (process);
- using (process) {
- process.Start ();
- if (onStarted != null)
- onStarted (process);
-
- // If the token is cancelled while we're running, kill the process.
- // Otherwise once we finish the Task.WhenAll we can remove this registration
- // as there is no longer any need to Kill the process.
- //
- // We wrap `stdout` and `stderr` in syncronized wrappers for safety in case they
- // end up writing to the same buffer, or they are the same object.
- using (cancellationToken.Register (() => KillProcess (process))) {
- if (psi.RedirectStandardOutput)
- output = ReadStreamAsync (process.StandardOutput, TextWriter.Synchronized (stdout));
-
- if (psi.RedirectStandardError)
- error = ReadStreamAsync (process.StandardError, TextWriter.Synchronized (stderr));
-
- await Task.WhenAll (new [] { output, error, exit }).ConfigureAwait (false);
- }
- // If we invoke 'KillProcess' our output, error and exit tasks will all complete normally.
- // To protected against passing the user incomplete data we have to call
- // `cancellationToken.ThrowIfCancellationRequested ()` here.
- cancellationToken.ThrowIfCancellationRequested ();
- return process.ExitCode;
- }
- }
-
- static void KillProcess (Process p)
- {
- try {
- p.Kill ();
- } catch (InvalidOperationException) {
- // If the process has already exited this could happen
- }
- }
-
- static Task WaitForExitAsync (Process process)
- {
- var exitDone = new TaskCompletionSource ();
- process.Exited += (o, e) => exitDone.TrySetResult (true);
- return exitDone.Task;
- }
-
- static async Task ReadStreamAsync (StreamReader stream, TextWriter destination)
- {
- int read;
- var buffer = new char [4096];
- while ((read = await stream.ReadAsync (buffer, 0, buffer.Length).ConfigureAwait (false)) > 0)
- destination.Write (buffer, 0, read);
- }
-
- ///
- /// Executes an Android Sdk tool and returns a result. The result is based on a function of the command output.
- ///
- public static Task ExecuteToolAsync (string exe, Func result, CancellationToken token, Action onStarted = null)
- {
- var tcs = new TaskCompletionSource ();
-
- var log = new StringWriter ();
- var error = new StringWriter ();
-
- var psi = new ProcessStartInfo (exe);
- psi.CreateNoWindow = true;
- psi.RedirectStandardInput = onStarted != null;
-
- var processTask = ProcessUtils.StartProcess (psi, log, error, token, onStarted);
- var exeName = Path.GetFileName (exe);
-
- processTask.ContinueWith (t => {
- var output = log.ToString ();
- var errorOutput = error.ToString ();
- log.Dispose ();
- error.Dispose ();
-
- if (t.IsCanceled) {
- tcs.TrySetCanceled ();
- return;
- }
-
- if (t.IsFaulted) {
- tcs.TrySetException (t.Exception.Flatten ().InnerException);
- return;
- }
-
- if (t.Result == 0) {
- tcs.TrySetResult (result != null ? result (output) : default (TResult));
- } else {
- var errorMessage = !string.IsNullOrEmpty (errorOutput) ? errorOutput : output;
-
- tcs.TrySetException (new InvalidOperationException (string.IsNullOrEmpty (errorMessage) ? exeName + " returned non-zero exit code" : string.Format ("{0} : {1}", t.Result, errorMessage)));
- }
- }, TaskContinuationOptions.ExecuteSynchronously);
-
- return tcs.Task;
- }
- }
-}
-
diff --git a/src/Xamarin.Android.Build.Utilities/Sdks/AndroidSdkBase.cs b/src/Xamarin.Android.Build.Utilities/Sdks/AndroidSdkBase.cs
deleted file mode 100644
index 60eb067eabe..00000000000
--- a/src/Xamarin.Android.Build.Utilities/Sdks/AndroidSdkBase.cs
+++ /dev/null
@@ -1,183 +0,0 @@
-using System;
-using System.Linq;
-using System.IO;
-using System.Collections.Generic;
-
-namespace Xamarin.Android.Build.Utilities
-{
- abstract class AndroidSdkBase
- {
- string[] allAndroidSdks = null;
- string[] allAndroidNdks = null;
-
- public string[] AllAndroidSdks {
- get {
- if (allAndroidSdks == null)
- allAndroidSdks = GetAllAvailableAndroidSdks ().Distinct ().ToArray ();
- return allAndroidSdks;
- }
- }
- public string[] AllAndroidNdks {
- get {
- if (allAndroidNdks == null)
- allAndroidNdks = GetAllAvailableAndroidNdks ().Distinct ().ToArray ();
- return allAndroidNdks;
- }
- }
-
- public string AndroidSdkPath { get; private set; }
- public string AndroidNdkPath { get; private set; }
- public string JavaSdkPath { get; private set; }
- public string JavaBinPath { get; private set; }
- public string AndroidToolsPath { get; private set; }
- public string AndroidPlatformToolsPath { get; private set; }
- public string AndroidToolsPathShort { get; private set; }
- public string AndroidPlatformToolsPathShort { get; private set; }
-
- public virtual string Adb { get; protected set; } = "adb";
- public virtual string Android { get; protected set; } = "android";
- public virtual string Emulator { get; protected set; } = "emulator";
- public virtual string Monitor { get; protected set; } = "monitor";
- public virtual string ZipAlign { get; protected set; } = "zipalign";
- public virtual string JarSigner { get; protected set; } = "jarsigner";
- public virtual string KeyTool { get; protected set; } = "keytool";
-
- public virtual string NdkStack { get; protected set; } = "ndk-stack";
- public abstract string NdkHostPlatform32Bit { get; }
- public abstract string NdkHostPlatform64Bit { get; }
- public virtual string Javac { get; protected set; } = "javac";
-
- public abstract string PreferedAndroidSdkPath { get; }
- public abstract string PreferedAndroidNdkPath { get; }
- public abstract string PreferedJavaSdkPath { get; }
-
- public virtual void Initialize (string androidSdkPath = null, string androidNdkPath = null, string javaSdkPath = null)
- {
- AndroidSdkPath = ValidateAndroidSdkLocation (androidSdkPath) ? androidSdkPath : AllAndroidSdks.FirstOrDefault ();
- AndroidNdkPath = ValidateAndroidNdkLocation (androidNdkPath) ? androidNdkPath : AllAndroidNdks.FirstOrDefault ();
- JavaSdkPath = ValidateJavaSdkLocation (javaSdkPath) ? javaSdkPath : GetJavaSdkPath ();
-
- if (!string.IsNullOrEmpty (JavaSdkPath)) {
- JavaBinPath = Path.Combine (JavaSdkPath, "bin");
- } else {
- JavaBinPath = null;
- }
-
- if (!string.IsNullOrEmpty (AndroidSdkPath)) {
- AndroidToolsPath = Path.Combine (AndroidSdkPath, "tools");
- AndroidToolsPathShort = GetShortFormPath (AndroidToolsPath);
- AndroidPlatformToolsPath = Path.Combine (AndroidSdkPath, "platform-tools");
- AndroidPlatformToolsPathShort = GetShortFormPath (AndroidPlatformToolsPath);
- } else {
- AndroidToolsPath = null;
- AndroidToolsPathShort = null;
- AndroidPlatformToolsPath = null;
- AndroidPlatformToolsPathShort = null;
- }
-
- if (!string.IsNullOrEmpty (AndroidNdkPath)) {
- // It would be nice if .NET had real globbing support in System.IO...
- string toolchainsDir = Path.Combine (AndroidNdkPath, "toolchains");
- IsNdk64Bit = Directory.EnumerateDirectories (toolchainsDir, "arm-linux-androideabi-*")
- .Any (dir => Directory.Exists (Path.Combine (dir, "prebuilt", NdkHostPlatform64Bit)));
- }
- // we need to look for extensions other than the default .exe|.bat
- // google have a habbit of changing them.
- Adb = GetExecutablePath (AndroidPlatformToolsPath, Adb);
- Android = GetExecutablePath (AndroidToolsPath, Android);
- Emulator = GetExecutablePath (AndroidToolsPath, Emulator);
- Monitor = GetExecutablePath (AndroidToolsPath, Monitor);
- NdkStack = GetExecutablePath (AndroidNdkPath, NdkStack);
- }
-
- protected abstract IEnumerable GetAllAvailableAndroidSdks ();
- protected abstract IEnumerable GetAllAvailableAndroidNdks ();
- protected abstract string GetJavaSdkPath ();
- protected abstract string GetShortFormPath (string path);
-
- public abstract void SetPreferredAndroidSdkPath (string path);
- public abstract void SetPreferredJavaSdkPath (string path);
- public abstract void SetPreferredAndroidNdkPath (string path);
-
- public bool IsNdk64Bit { get; private set; }
-
- public string NdkHostPlatform {
- get { return IsNdk64Bit ? NdkHostPlatform64Bit : NdkHostPlatform32Bit; }
- }
-
- ///
- /// Checks that a value is the location of an Android SDK.
- ///
- public bool ValidateAndroidSdkLocation (string loc)
- {
- return !string.IsNullOrEmpty (loc) && FindExecutableInDirectory (Adb, Path.Combine (loc, "platform-tools")).Any ();
- }
-
- ///
- /// Checks that a value is the location of a Java SDK.
- ///
- public virtual bool ValidateJavaSdkLocation (string loc)
- {
- return !string.IsNullOrEmpty (loc) && FindExecutableInDirectory (JarSigner, Path.Combine (loc, "bin")).Any ();
- }
-
- ///
- /// Checks that a value is the location of an Android SDK.
- ///
- public bool ValidateAndroidNdkLocation (string loc)
- {
- return !string.IsNullOrEmpty (loc) && FindExecutableInDirectory(NdkStack, loc).Any();
- }
-
- protected IEnumerable FindExecutableInPath (string executable)
- {
- var path = Environment.GetEnvironmentVariable ("PATH");
- var pathDirs = path.Split (new char[] { Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries);
-
- foreach (var dir in pathDirs) {
- foreach (var directory in FindExecutableInDirectory(executable, dir)) {
- yield return directory;
- }
- }
- }
-
- protected IEnumerable FindExecutableInDirectory(string executable, string dir)
- {
- foreach (var exe in Executables (executable))
- if (File.Exists (Path.Combine (dir, exe)))
- yield return dir;
- }
-
- IEnumerable Executables (string executable)
- {
- yield return executable;
- var pathExt = Environment.GetEnvironmentVariable ("PATHEXT");
- var pathExts = pathExt?.Split (new char [] { Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries);
-
- if (pathExts == null)
- yield break;
-
- foreach (var ext in pathExts)
- yield return Path.ChangeExtension (executable, ext);
- }
-
- protected string NullIfEmpty (string s)
- {
- if (s == null || s.Length != 0)
- return s;
-
- return null;
- }
-
- string GetExecutablePath (string dir, string exe)
- {
- if (string.IsNullOrEmpty (dir))
- return exe;
- foreach (var e in Executables (exe))
- if (File.Exists (Path.Combine (dir, e)))
- return e;
- return exe;
- }
- }
-}
-
diff --git a/src/Xamarin.Android.Build.Utilities/Sdks/AndroidSdkUnix.cs b/src/Xamarin.Android.Build.Utilities/Sdks/AndroidSdkUnix.cs
deleted file mode 100644
index 0545c90cdc0..00000000000
--- a/src/Xamarin.Android.Build.Utilities/Sdks/AndroidSdkUnix.cs
+++ /dev/null
@@ -1,233 +0,0 @@
-using System;
-using System.Xml;
-using System.Xml.Linq;
-using System.Collections.Generic;
-using System.IO;
-
-namespace Xamarin.Android.Build.Utilities
-{
- class AndroidSdkUnix : AndroidSdkBase
- {
- public override string NdkHostPlatform32Bit {
- get { return OS.IsMac ? "darwin-x86" : "linux-x86"; }
- }
- public override string NdkHostPlatform64Bit {
- get { return OS.IsMac ? "darwin-x86_64" : "linux-x86_64"; }
- }
-
- public override string PreferedAndroidSdkPath {
- get {
- var config_file = GetUnixConfigFile ();
- var androidEl = config_file.Root.Element ("android-sdk");
-
- if (androidEl != null) {
- var path = (string)androidEl.Attribute ("path");
-
- if (ValidateAndroidSdkLocation (path))
- return path;
- }
- return null;
- }
- }
-
- public override string PreferedAndroidNdkPath {
- get {
- var config_file = GetUnixConfigFile ();
- var androidEl = config_file.Root.Element ("android-ndk");
-
- if (androidEl != null) {
- var path = (string)androidEl.Attribute ("path");
-
- if (ValidateAndroidNdkLocation (path))
- return path;
- }
- return null;
- }
- }
-
- public override string PreferedJavaSdkPath {
- get {
- var config_file = GetUnixConfigFile ();
- var javaEl = config_file.Root.Element ("java-sdk");
-
- if (javaEl != null) {
- var path = (string)javaEl.Attribute ("path");
-
- if (ValidateJavaSdkLocation (path))
- return path;
- }
- return null;
- }
- }
-
- protected override IEnumerable GetAllAvailableAndroidSdks ()
- {
- var preferedSdkPath = PreferedAndroidSdkPath;
- if (!string.IsNullOrEmpty (preferedSdkPath))
- yield return preferedSdkPath;
-
- // Look in PATH
- foreach (var path in FindExecutableInPath (Adb)) {
- // Strip off "platform-tools"
- var dir = Path.GetDirectoryName (path);
-
- if (ValidateAndroidSdkLocation (dir))
- yield return dir;
- }
- }
-
- protected override string GetJavaSdkPath ()
- {
- var preferedJavaSdkPath = PreferedJavaSdkPath;
- if (!string.IsNullOrEmpty (preferedJavaSdkPath))
- return preferedJavaSdkPath;
-
- // Look in PATH
- foreach (var path in FindExecutableInPath (JarSigner)) {
- // Strip off "bin"
- var dir = Path.GetDirectoryName (path);
-
- if (ValidateJavaSdkLocation (dir))
- return dir;
- }
-
- return null;
- }
-
- public override bool ValidateJavaSdkLocation (string loc)
- {
- var result = base.ValidateJavaSdkLocation (loc);
-
- if (result) {
- // handle apple's java stub
- const string javaHomeExe = "/usr/libexec/java_home";
-
- if (File.Exists (javaHomeExe)) {
- // returns true if there is a java installed
- var javaHomeTask = ProcessUtils.ExecuteToolAsync (javaHomeExe,
- (output) => {
- if (output.Contains ("(null)")) {
- return false;
- }
-
- return true;
- }, System.Threading.CancellationToken.None
- );
-
- if (!javaHomeTask.Result) {
- return false;
- }
- }
- }
-
- return result;
- }
-
- protected override IEnumerable GetAllAvailableAndroidNdks ()
- {
- var preferedNdkPath = PreferedAndroidNdkPath;
- if (!string.IsNullOrEmpty (preferedNdkPath))
- yield return preferedNdkPath;
-
- // Look in PATH
- foreach (var path in FindExecutableInPath (NdkStack)) {
- if (ValidateAndroidNdkLocation (path))
- yield return path;
- }
- }
-
- protected override string GetShortFormPath (string path)
- {
- // This is a Windows-ism, don't do anything for Unix
- return path;
- }
-
- public override void SetPreferredAndroidSdkPath (string path)
- {
- path = NullIfEmpty (path);
-
- var doc = GetUnixConfigFile ();
- var androidEl = doc.Root.Element ("android-sdk");
-
- if (androidEl == null) {
- androidEl = new XElement ("android-sdk");
- doc.Root.Add (androidEl);
- }
-
- androidEl.SetAttributeValue ("path", path);
- doc.Save (UnixConfigPath);
- }
-
- public override void SetPreferredJavaSdkPath (string path)
- {
- path = NullIfEmpty (path);
-
- var doc = GetUnixConfigFile ();
- var javaEl = doc.Root.Element ("java-sdk");
-
- if (javaEl == null) {
- javaEl = new XElement ("java-sdk");
- doc.Root.Add (javaEl);
- }
-
- javaEl.SetAttributeValue ("path", path);
- doc.Save (UnixConfigPath);
- }
-
- public override void SetPreferredAndroidNdkPath (string path)
- {
- path = NullIfEmpty (path);
-
- var doc = GetUnixConfigFile ();
- var androidEl = doc.Root.Element ("android-ndk");
-
- if (androidEl == null) {
- androidEl = new XElement ("android-ndk");
- doc.Root.Add (androidEl);
- }
-
- androidEl.SetAttributeValue ("path", path);
- doc.Save (UnixConfigPath);
- }
-
- private static string UnixConfigPath {
- get {
- var p = Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData);
- return Path.Combine (Path.Combine (p, "xbuild"), "monodroid-config.xml");
- }
- }
-
- private static XDocument GetUnixConfigFile ()
- {
- var file = UnixConfigPath;
- XDocument doc = null;
- if (!File.Exists (file)) {
- string dir = Path.GetDirectoryName (file);
- if (!Directory.Exists (dir))
- Directory.CreateDirectory (dir);
- } else {
- try {
- doc = XDocument.Load (file);
- } catch (Exception ex) {
- AndroidLogger.LogError ("Could not load monodroid configuration file", ex);
-
- // move out of the way and create a new one
- doc = new XDocument (new XElement ("monodroid"));
- var newFileName = file + ".old";
- if (File.Exists (newFileName)) {
- File.Delete (newFileName);
- }
-
- File.Move (file, newFileName);
- }
- }
-
- if (doc == null || doc.Root == null) {
- doc = new XDocument (new XElement ("monodroid"));
- }
- return doc;
- }
-
- }
-}
-
diff --git a/src/Xamarin.Android.Build.Utilities/Sdks/AndroidSdkWindows.cs b/src/Xamarin.Android.Build.Utilities/Sdks/AndroidSdkWindows.cs
deleted file mode 100644
index 21ebd3e94a0..00000000000
--- a/src/Xamarin.Android.Build.Utilities/Sdks/AndroidSdkWindows.cs
+++ /dev/null
@@ -1,202 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-
-namespace Xamarin.Android.Build.Utilities
-{
- class AndroidSdkWindows : AndroidSdkBase
- {
- const string MDREG_KEY = @"SOFTWARE\Novell\Mono for Android";
- const string MDREG_ANDROID_SDK = "AndroidSdkDirectory";
- const string MDREG_ANDROID_NDK = "AndroidNdkDirectory";
- const string MDREG_JAVA_SDK = "JavaSdkDirectory";
- const string ANDROID_INSTALLER_PATH = @"SOFTWARE\Android SDK Tools";
- const string ANDROID_INSTALLER_KEY = "Path";
- const string XAMARIN_ANDROID_INSTALLER_PATH = @"SOFTWARE\Xamarin\MonoAndroid";
- const string XAMARIN_ANDROID_INSTALLER_KEY = "PrivateAndroidSdkPath";
-
- public override string ZipAlign { get; protected set; } = "zipalign.exe";
- public override string JarSigner { get; protected set; } = "jarsigner.exe";
- public override string KeyTool { get; protected set; } = "keytool.exe";
-
- public override string NdkHostPlatform32Bit { get { return "windows"; } }
- public override string NdkHostPlatform64Bit { get { return "windows-x86_64"; } }
- public override string Javac { get; protected set; } = "javac.exe";
-
- public override string PreferedAndroidSdkPath {
- get {
- var wow = RegistryEx.Wow64.Key32;
- if (CheckRegistryKeyForExecutable (RegistryEx.CurrentUser, MDREG_KEY, MDREG_ANDROID_SDK, wow, "platform-tools", Adb))
- return RegistryEx.GetValueString (RegistryEx.CurrentUser, MDREG_KEY, MDREG_ANDROID_SDK, wow);
- return null;
- }
- }
- public override string PreferedAndroidNdkPath {
- get {
- var wow = RegistryEx.Wow64.Key32;
- if (CheckRegistryKeyForExecutable (RegistryEx.CurrentUser, MDREG_KEY, MDREG_ANDROID_NDK, wow, ".", NdkStack))
- return RegistryEx.GetValueString (RegistryEx.CurrentUser, MDREG_KEY, MDREG_ANDROID_NDK, wow);
- return null;
- }
- }
- public override string PreferedJavaSdkPath {
- get {
- var wow = RegistryEx.Wow64.Key32;
- if (CheckRegistryKeyForExecutable (RegistryEx.CurrentUser, MDREG_KEY, MDREG_JAVA_SDK, wow, "bin", JarSigner))
- return RegistryEx.GetValueString (RegistryEx.CurrentUser, MDREG_KEY, MDREG_JAVA_SDK, wow);
- return null;
- }
- }
-
- protected override IEnumerable GetAllAvailableAndroidSdks ()
- {
- var roots = new[] { RegistryEx.CurrentUser, RegistryEx.LocalMachine };
- var wow = RegistryEx.Wow64.Key32;
-
- AndroidLogger.LogInfo ("sdk", "Looking for Android SDK..");
-
- // Check for the key the user gave us in the VS/addin options
- foreach (var root in roots)
- if (CheckRegistryKeyForExecutable (root, MDREG_KEY, MDREG_ANDROID_SDK, wow, "platform-tools", Adb))
- yield return RegistryEx.GetValueString (root, MDREG_KEY, MDREG_ANDROID_SDK, wow);
-
- // Check for the key written by the Xamarin installer
- if (CheckRegistryKeyForExecutable (RegistryEx.CurrentUser, XAMARIN_ANDROID_INSTALLER_PATH, XAMARIN_ANDROID_INSTALLER_KEY, wow, "platform-tools", Adb))
- yield return RegistryEx.GetValueString (RegistryEx.CurrentUser, XAMARIN_ANDROID_INSTALLER_PATH, XAMARIN_ANDROID_INSTALLER_KEY, wow);
-
- // Check for the key written by the Android SDK installer
- foreach (var root in roots)
- if (CheckRegistryKeyForExecutable (root, ANDROID_INSTALLER_PATH, ANDROID_INSTALLER_KEY, wow, "platform-tools", Adb))
- yield return RegistryEx.GetValueString (root, ANDROID_INSTALLER_PATH, ANDROID_INSTALLER_KEY, wow);
-
- // Check some hardcoded paths for good measure
- var xamarin_private = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData), "Xamarin", "MonoAndroid", "android-sdk-windows");
- var android_default = Path.Combine (OS.ProgramFilesX86, "Android", "android-sdk-windows");
- var cdrive_default = @"C:\android-sdk-windows";
-
- if (ValidateAndroidSdkLocation (xamarin_private))
- yield return xamarin_private;
-
- if (ValidateAndroidSdkLocation (android_default))
- yield return android_default;
-
- if (ValidateAndroidSdkLocation (cdrive_default))
- yield return cdrive_default;
- }
-
- protected override string GetJavaSdkPath ()
- {
- // check the user specified path
- var roots = new[] { RegistryEx.CurrentUser, RegistryEx.LocalMachine };
- const RegistryEx.Wow64 wow = RegistryEx.Wow64.Key32;
-
- foreach (var root in roots) {
- if (CheckRegistryKeyForExecutable (root, MDREG_KEY, MDREG_JAVA_SDK, wow, "bin", JarSigner))
- return RegistryEx.GetValueString (root, MDREG_KEY, MDREG_JAVA_SDK, wow);
- }
-
- string subkey = @"SOFTWARE\JavaSoft\Java Development Kit";
-
- AndroidLogger.LogInfo ("sdk", "Looking for Java 6 SDK..");
-
- foreach (var wow64 in new[] { RegistryEx.Wow64.Key32, RegistryEx.Wow64.Key64 }) {
- string key_name = string.Format (@"{0}\{1}\{2}", "HKLM", subkey, "CurrentVersion");
- var currentVersion = RegistryEx.GetValueString (RegistryEx.LocalMachine, subkey, "CurrentVersion", wow64);
-
- if (!string.IsNullOrEmpty (currentVersion)) {
- AndroidLogger.LogInfo ("sdk", " Key {0} found.", key_name);
-
- // No matter what the CurrentVersion is, look for 1.6 or 1.7 or 1.8
- if (CheckRegistryKeyForExecutable (RegistryEx.LocalMachine, subkey + "\\" + "1.6", "JavaHome", wow64, "bin", JarSigner))
- return RegistryEx.GetValueString (RegistryEx.LocalMachine, subkey + "\\" + "1.6", "JavaHome", wow64);
-
- if (CheckRegistryKeyForExecutable (RegistryEx.LocalMachine, subkey + "\\" + "1.7", "JavaHome", wow64, "bin", JarSigner))
- return RegistryEx.GetValueString (RegistryEx.LocalMachine, subkey + "\\" + "1.7", "JavaHome", wow64);
-
- if (CheckRegistryKeyForExecutable (RegistryEx.LocalMachine, subkey + "\\" + "1.8", "JavaHome", wow64, "bin", JarSigner))
- return RegistryEx.GetValueString (RegistryEx.LocalMachine, subkey + "\\" + "1.8", "JavaHome", wow64);
- }
-
- AndroidLogger.LogInfo ("sdk", " Key {0} not found.", key_name);
- }
-
- // We ran out of things to check..
- return null;
- }
-
- protected override IEnumerable GetAllAvailableAndroidNdks ()
- {
- var roots = new[] { RegistryEx.CurrentUser, RegistryEx.LocalMachine };
- var wow = RegistryEx.Wow64.Key32;
-
- AndroidLogger.LogInfo ("sdk", "Looking for Android NDK..");
-
- // Check for the key the user gave us in the VS/addin options
- foreach (var root in roots)
- if (CheckRegistryKeyForExecutable (root, MDREG_KEY, MDREG_ANDROID_NDK, wow, ".", NdkStack))
- yield return RegistryEx.GetValueString (root, MDREG_KEY, MDREG_ANDROID_NDK, wow);
-
- /*
- // Check for the key written by the Xamarin installer
- if (CheckRegistryKeyForExecutable (RegistryEx.CurrentUser, XAMARIN_ANDROID_INSTALLER_PATH, XAMARIN_ANDROID_INSTALLER_KEY, wow, "platform-tools", Adb))
- yield return RegistryEx.GetValueString (RegistryEx.CurrentUser, XAMARIN_ANDROID_INSTALLER_PATH, XAMARIN_ANDROID_INSTALLER_KEY, wow);
- */
-
- // Check some hardcoded paths for good measure
- var xamarin_private = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData), "Xamarin", "MonoAndroid");
- var android_default = Path.Combine (OS.ProgramFilesX86, "Android");
- var cdrive_default = @"C:\";
-
- foreach (var basePath in new string [] {xamarin_private, android_default, cdrive_default})
- if (Directory.Exists (basePath))
- foreach (var dir in Directory.GetDirectories (basePath, "android-ndk-r*"))
- if (ValidateAndroidNdkLocation (dir))
- yield return dir;
- }
-
- protected override string GetShortFormPath (string path)
- {
- return KernelEx.GetShortPathName (path);
- }
-
- public override void SetPreferredAndroidSdkPath (string path)
- {
- RegistryEx.SetValueString (RegistryEx.CurrentUser, MDREG_KEY, MDREG_ANDROID_SDK, path ?? "", RegistryEx.Wow64.Key32);
- }
-
- public override void SetPreferredJavaSdkPath (string path)
- {
- RegistryEx.SetValueString (RegistryEx.CurrentUser, MDREG_KEY, MDREG_JAVA_SDK, path ?? "", RegistryEx.Wow64.Key32);
- }
-
- public override void SetPreferredAndroidNdkPath (string path)
- {
- RegistryEx.SetValueString (RegistryEx.CurrentUser, MDREG_KEY, MDREG_ANDROID_NDK, path ?? "", RegistryEx.Wow64.Key32);
- }
-
- #region Helper Methods
- private bool CheckRegistryKeyForExecutable (UIntPtr key, string subkey, string valueName, RegistryEx.Wow64 wow64, string subdir, string exe)
- {
- string key_name = string.Format (@"{0}\{1}\{2}", key == RegistryEx.CurrentUser ? "HKCU" : "HKLM", subkey, valueName);
-
- var path = NullIfEmpty (RegistryEx.GetValueString (key, subkey, valueName, wow64));
-
- if (path == null) {
- AndroidLogger.LogInfo ("sdk", " Key {0} not found.", key_name);
- return false;
- }
-
- if (!FindExecutableInDirectory (exe, Path.Combine (path, subdir)).Any ()) {
- AndroidLogger.LogInfo ("sdk", " Key {0} found:\n Path does not contain {1} in \\{2} ({3}).", key_name, exe, subdir, path);
- return false;
- }
-
- AndroidLogger.LogInfo ("sdk", " Key {0} found:\n Path contains {1} in \\{2} ({3}).", key_name, exe, subdir, path);
-
- return true;
- }
- #endregion
- }
-}
-
diff --git a/src/Xamarin.Android.Build.Utilities/Sdks/MonoDroidSdkBase.cs b/src/Xamarin.Android.Build.Utilities/Sdks/MonoDroidSdkBase.cs
deleted file mode 100644
index dfdb9829a50..00000000000
--- a/src/Xamarin.Android.Build.Utilities/Sdks/MonoDroidSdkBase.cs
+++ /dev/null
@@ -1,292 +0,0 @@
-using System;
-using System.Linq;
-using System.IO;
-using System.Collections.Generic;
-using System.Xml;
-
-namespace Xamarin.Android.Build.Utilities
-{
- abstract class MonoDroidSdkBase
- {
- protected readonly static string DebugRuntime = "Mono.Android.DebugRuntime-debug.apk";
- protected readonly static string ClassParseExe = "class-parse.exe";
- protected readonly static string GeneratorScript = "generator";
-
- // I can never remember the difference between SdkPath and anything else...
- [Obsolete ("Do not use.")]
- public string SdkPath { get; private set; }
-
- // Contains mandroid
- public string BinPath { get; private set; }
-
- // Not actually shipped...
- public string IncludePath { get; private set; }
-
- // Contains Mono.Android.DebugRuntime-*.apk, platforms/*/*.apk.
- public string RuntimePath { get; private set; }
-
- // Root directory for XA libraries, contains designer dependencies
- public string LibrariesPath { get; private set; }
-
- // Contains mscorlib.dll
- public string BclPath { get; private set; }
-
- public int SharedRuntimeVersion { get; private set; }
-
- // expectedRuntimePath: contains Mono.Android.DebugRuntime-*.apk
- // binPath: contains mandroid
- // mscorlibDir: contains mscorlib.dll
- public void Initialize (string expectedRuntimePath = null, string binPath = null, string bclPath = null)
- {
- var runtimePath = GetValidPath ("MonoAndroidToolsPath", expectedRuntimePath, ValidateRuntime, () => FindRuntime ());
- if (runtimePath != null) {
- binPath = GetValidPath ("MonoAndroidBinPath", binPath, ValidateBin, () => FindBin (runtimePath));
- bclPath = GetValidPath ("mscorlib.dll", bclPath, ValidateFramework, () => FindFramework (runtimePath));
- } else {
- if (expectedRuntimePath != null)
- AndroidLogger.LogWarning (null, "Runtime was not found at {0}", expectedRuntimePath);
- binPath = bclPath = null;
- }
-
- if (runtimePath == null || binPath == null || bclPath == null) {
- Reset ();
- return;
- }
-
- RuntimePath = runtimePath;
- #pragma warning disable 0618
- SdkPath = Path.GetFullPath (Path.Combine (runtimePath, "..", ".."));
- #pragma warning restore 0618
- BinPath = binPath;
- BclPath = bclPath;
- LibrariesPath = FindLibraries (runtimePath);
-
- IncludePath = FindInclude (runtimePath);
- if (IncludePath != null && !Directory.Exists (IncludePath))
- IncludePath = null;
-
- SharedRuntimeVersion = GetCurrentSharedRuntimeVersion ();
- FindSupportedFrameworks ();
- }
-
- static string GetValidPath (string description, string path, Func validator, Func defaultPath)
- {
- if (!string.IsNullOrEmpty (path)) {
- if (Directory.Exists (path)) {
- if (validator (path))
- return path;
- AndroidLogger.LogWarning (null, "{0} path '{1}' is explicitly specified, but it was not valid; skipping.", description, path);
- } else
- AndroidLogger.LogWarning (null, "{0} path '{1}' is explicitly specified, but it was not found; skipping.", description, path);
- }
- path = defaultPath ();
- if (path != null && validator (path))
- return path;
- if (path != null)
- AndroidLogger.LogWarning (null, "{0} path is defaulted to '{1}', but it was not valid; skipping", description, path);
- else
- AndroidLogger.LogWarning (null, "{0} path is not found and no default location is provided; skipping", description);
- return null;
- }
-
- public void Reset ()
- {
- #pragma warning disable 0618
- SdkPath = BinPath = IncludePath = RuntimePath = BclPath = null;
- #pragma warning restore 0618
- SharedRuntimeVersion = 0;
- }
-
- protected abstract string FindRuntime ();
- protected abstract string FindFramework (string runtimePath);
-
- // Check for platform-specific `mandroid` name
- protected abstract bool ValidateBin (string binPath);
-
- protected static bool ValidateRuntime (string loc)
- {
- return !string.IsNullOrWhiteSpace (loc) &&
- (File.Exists (Path.Combine (loc, DebugRuntime)) || // Normal/expected
- File.Exists (Path.Combine (loc, ClassParseExe)) || // Normal/expected
- File.Exists (Path.Combine (loc, "Ionic.Zip.dll"))); // Wrench builds
- }
-
- protected static bool ValidateFramework (string loc)
- {
- return loc != null && File.Exists (Path.Combine (loc, "mscorlib.dll"));
- }
-
- public string FindVersionFile ()
- {
- #pragma warning disable 0618
- if (string.IsNullOrEmpty (SdkPath))
- return null;
- #pragma warning restore 0618
- foreach (var loc in GetVersionFileLocations ()) {
- if (File.Exists (loc)) {
- return loc;
- }
- }
- return null;
- }
-
- protected virtual IEnumerable GetVersionFileLocations ()
- {
- #pragma warning disable 0618
- yield return Path.Combine (SdkPath, "Version");
- #pragma warning restore 0618
- }
-
- protected abstract string FindBin (string runtimePath);
-
- protected abstract string FindInclude (string runtimePath);
-
- protected abstract string FindLibraries (string runtimePath);
-
- [Obsolete ("Do not use.")]
- public string GetPlatformNativeLibPath (string abi)
- {
- return FindPlatformNativeLibPath (SdkPath, abi);
- }
-
- [Obsolete ("Do not use.")]
- public string GetPlatformNativeLibPath (AndroidTargetArch arch)
- {
- return FindPlatformNativeLibPath (SdkPath, GetMonoDroidArchName (arch));
- }
-
- [Obsolete ("Do not use.")]
- static string GetMonoDroidArchName (AndroidTargetArch arch)
- {
- switch (arch) {
- case AndroidTargetArch.Arm:
- return "armeabi";
- case AndroidTargetArch.Mips:
- return "mips";
- case AndroidTargetArch.X86:
- return "x86";
- }
- return null;
- }
-
- [Obsolete]
- protected string FindPlatformNativeLibPath (string sdk, string arch)
- {
- return Path.Combine (sdk, "lib", arch);
- }
-
- static XmlReaderSettings GetSafeReaderSettings ()
- {
- //allow DTD but not try to resolve it from web
- return new XmlReaderSettings {
- CloseInput = true,
- DtdProcessing = DtdProcessing.Ignore,
- XmlResolver = null,
- };
- }
-
- int GetCurrentSharedRuntimeVersion ()
- {
- string file = Path.Combine (RuntimePath, "Mono.Android.DebugRuntime-debug.xml");
-
- return GetManifestVersion (file);
- }
-
- internal static int GetManifestVersion (string file)
- {
- // It seems that MfA 1.0 on Windows didn't include the xml files to get the runtime version.
- if (!File.Exists (file))
- return int.MaxValue;
-
- try {
- using (var r = XmlReader.Create (file, GetSafeReaderSettings())) {
- if (r.MoveToContent () == XmlNodeType.Element && r.MoveToAttribute ("android:versionCode")) {
- int value;
- if (int.TryParse (r.Value, out value))
- return value;
- AndroidLogger.LogInfo ("Cannot parse runtime version code: ({0})", r.Value);
- }
- }
- } catch (Exception ex) {
- AndroidLogger.LogError ("Error trying to find shared runtime version", ex);
- }
- return int.MaxValue;
- }
-
- internal static Version ToVersion (string frameworkDir)
- {
- string version = Path.GetFileName (frameworkDir);
- if (!version.StartsWith ("v", StringComparison.OrdinalIgnoreCase)) {
- // wat?
- return new Version ();
- }
- version = version.Substring (1);
- Version v;
- if (Version.TryParse (version, out v))
- return v;
- return new Version ();
- }
-
- void FindSupportedFrameworks ()
- {
- string bclDir = MonoDroidSdk.FrameworkPath;
- string frameworksDir = Path.GetDirectoryName (bclDir);
- foreach (var framework in Directory.EnumerateDirectories (frameworksDir).Select (ToVersion)) {
- if (framework.Major == 0)
- continue;
- string apiLevel;
- if (FrameworkToApiLevels.TryGetValue (framework, out apiLevel))
- SupportedFrameworks.Add (framework, apiLevel);
- }
- }
-
- readonly Dictionary SupportedFrameworks = new Dictionary ();
-
- static readonly Dictionary FrameworkToApiLevels = new Dictionary (AndroidVersion.KnownVersions.ToDictionary (k => k.Version, v => v.ApiLevel.ToString ()));
- static readonly Dictionary LegacyFrameworkToApiLevels = new Dictionary {
- { new Version (4, 5), "21" } // L Preview
- };
-
- public IEnumerable GetSupportedApiLevels ()
- {
- return SupportedFrameworks.Select (e => e.Value);
- }
-
- public string GetApiLevelForFrameworkVersion (string framework)
- {
- Version v;
- if (!Version.TryParse (framework.TrimStart ('v'), out v))
- return null;
- string apiLevel;
- if (SupportedFrameworks.TryGetValue (v, out apiLevel)
- || FrameworkToApiLevels.TryGetValue (v, out apiLevel)
- || LegacyFrameworkToApiLevels.TryGetValue (v, out apiLevel))
- return apiLevel;
- return null;
- }
-
- public string GetFrameworkVersionForApiLevel (string apiLevel)
- {
- // API level 9 was discontinued immediately for 10, in the rare case we get it just upgrade the number
- if (apiLevel == "9")
- apiLevel = "10";
- var maxFrameworkVersion = SupportedFrameworks.Concat (FrameworkToApiLevels)
- .Where (e => e.Value == apiLevel)
- .OrderByDescending (e => e.Key, Comparer.Default)
- .Select (e => e.Key)
- .FirstOrDefault ();
- if (maxFrameworkVersion != null)
- return "v" + maxFrameworkVersion;
- return null;
- }
-
- ///
- /// Determines if the given apiLevel is supported by an installed Framework
- ///
- public bool IsSupportedFrameworkLevel (string apiLevel)
- {
- return SupportedFrameworks.Any ((sf => sf.Value == apiLevel));
- }
- }
-}
-
diff --git a/src/Xamarin.Android.Build.Utilities/Sdks/MonoDroidSdkUnix.cs b/src/Xamarin.Android.Build.Utilities/Sdks/MonoDroidSdkUnix.cs
deleted file mode 100644
index ebe35c2d08a..00000000000
--- a/src/Xamarin.Android.Build.Utilities/Sdks/MonoDroidSdkUnix.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-using System;
-using System.IO;
-using System.Linq;
-using System.Collections.Generic;
-
-namespace Xamarin.Android.Build.Utilities
-{
- class MonoDroidSdkUnix : MonoDroidSdkBase
- {
- readonly static string[] RuntimeToFrameworkPaths = new[]{
- Path.Combine ("..", "..", "..", ".xamarin.android", "lib", "xbuild-frameworks", "MonoAndroid"),
- Path.Combine ("..", "xbuild-frameworks", "MonoAndroid"),
- Path.Combine ("..", "mono", "2.1"),
- };
-
- readonly static string[] SearchPaths = {
- "/Library/Frameworks/Xamarin.Android.framework/Versions/Current/lib/mandroid",
- "/Developer/MonoAndroid/usr/lib/mandroid",
- "/opt/mono-android/lib/mandroid"
- };
-
- protected override string FindRuntime ()
- {
- string monoAndroidPath = Environment.GetEnvironmentVariable ("MONO_ANDROID_PATH");
- if (!string.IsNullOrEmpty (monoAndroidPath)) {
- string libMandroid = Path.Combine (monoAndroidPath, "lib", "mandroid");
- if (Directory.Exists (libMandroid)) {
- if (ValidateRuntime (libMandroid))
- return libMandroid;
- AndroidLogger.LogInfo (null, "MONO_ANDROID_PATH points to {0}, but it is invalid.", monoAndroidPath);
- } else
- AndroidLogger.LogInfo (null, "MONO_ANDROID_PATH points to {0}, but it does not exist.", monoAndroidPath);
- }
-
- // check also in the users folder
- var personal = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
- var additionalSearchPaths = new [] {
- // for Mono.Posix and Mono.Data.Sqlite builds in xamarin-android.
- monoAndroidPath = Path.GetFullPath (Path.Combine (new Uri (GetType ().Assembly.CodeBase).LocalPath, "..", "..", "..", "..", "..", "lib", "mandroid")),
- Path.Combine (personal, @".xamarin.android/lib/mandroid")
- };
-
- return additionalSearchPaths.Concat (SearchPaths).FirstOrDefault (ValidateRuntime);
- }
-
- protected override bool ValidateBin (string binPath)
- {
- return !string.IsNullOrWhiteSpace (binPath) &&
- File.Exists (Path.Combine (binPath, GeneratorScript));
- }
-
- protected override string FindFramework (string runtimePath)
- {
- foreach (var relativePath in RuntimeToFrameworkPaths) {
- var fullPath = Path.GetFullPath (Path.Combine (runtimePath, relativePath));
- if (Directory.Exists (fullPath)) {
- if (ValidateFramework (fullPath))
- return fullPath;
-
- // check to see if full path is the folder that contains each framework version, eg contains folders of the form v1.0, v2.3 etc
- var subdirs = Directory.GetDirectories (fullPath, "v*").OrderBy (x => x).ToArray ();
- foreach (var subdir in subdirs) {
- if (ValidateFramework (subdir))
- return subdir;
- }
- }
- }
-
- return null;
- }
-
- protected override string FindBin (string runtimePath)
- {
- string binPath = Path.GetFullPath (Path.Combine (runtimePath, "..", "..", "bin"));
- if (File.Exists (Path.Combine (binPath, GeneratorScript)))
- return binPath;
- return null;
- }
-
- protected override string FindInclude (string runtimePath)
- {
- string includeDir = Path.GetFullPath (Path.Combine (runtimePath, "..", "..", "include"));
- if (Directory.Exists (includeDir))
- return includeDir;
- return null;
- }
-
- protected override string FindLibraries (string runtimePath)
- {
- return Path.GetFullPath (Path.Combine (runtimePath, ".."));
- }
-
- protected override IEnumerable GetVersionFileLocations ()
- {
- yield return Path.GetFullPath (Path.Combine (RuntimePath, "..", "..", "Version"));
- string sdkPath = Path.GetDirectoryName (Path.GetDirectoryName (RuntimePath));
- if (Path.GetFileName (sdkPath) == "usr")
- yield return Path.GetFullPath (Path.Combine (Path.GetDirectoryName (sdkPath), "Version"));
- }
- }
-}
-
diff --git a/src/Xamarin.Android.Build.Utilities/Sdks/MonoDroidSdkWindows.cs b/src/Xamarin.Android.Build.Utilities/Sdks/MonoDroidSdkWindows.cs
deleted file mode 100644
index a5905cec24c..00000000000
--- a/src/Xamarin.Android.Build.Utilities/Sdks/MonoDroidSdkWindows.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-using System;
-using System.IO;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Xamarin.Android.Build.Utilities
-{
- class MonoDroidSdkWindows : MonoDroidSdkBase
- {
- protected override string FindRuntime ()
- {
- string monoAndroidPath = Environment.GetEnvironmentVariable ("MONO_ANDROID_PATH");
- if (!string.IsNullOrEmpty (monoAndroidPath)) {
- string libMandroid = Path.Combine (monoAndroidPath, "lib", "mandroid");
- if (Directory.Exists (libMandroid) && ValidateRuntime (libMandroid))
- return libMandroid;
- }
- string xamarinSdk = Path.Combine (OS.ProgramFilesX86, "MSBuild", "Xamarin", "Android");
- return Directory.Exists (xamarinSdk)
- ? xamarinSdk
- : OS.ProgramFilesX86 + @"\MSBuild\Novell";
- }
-
- static readonly string[] RuntimeToFrameworkPaths = new []{
- Path.Combine ("..", "..", "..", "Reference Assemblies", "Microsoft", "Framework", "MonoAndroid"),
- Path.Combine (OS.ProgramFilesX86, "Reference Assemblies", "Microsoft", "Framework", "MonoAndroid"),
- };
-
- protected override string FindFramework (string runtimePath)
- {
- foreach (var relativePath in RuntimeToFrameworkPaths) {
- var fullPath = Path.GetFullPath (Path.Combine (runtimePath, relativePath));
- if (Directory.Exists (fullPath)) {
- if (ValidateFramework (fullPath))
- return fullPath;
-
- // check to see if full path is the folder that contains each framework version, eg contains folders of the form v1.0, v2.3 etc
- var subdirs = Directory.GetDirectories (fullPath, "v*").OrderBy (x => x).ToArray ();
- foreach (var subdir in subdirs) {
- if (ValidateFramework (subdir))
- return subdir;
- }
- }
- }
-
- return null;
- }
-
- protected override string FindBin (string runtimePath)
- {
- return runtimePath;
- }
-
- protected override bool ValidateBin (string binPath)
- {
- return !string.IsNullOrWhiteSpace (binPath) &&
- File.Exists (Path.Combine (binPath, "generator.exe"));
- }
-
- protected override string FindInclude (string runtimePath)
- {
- return Path.GetFullPath (Path.Combine (runtimePath, "include"));
- }
-
- protected override string FindLibraries (string runtimePath)
- {
- return Path.GetFullPath (runtimePath);
- }
-
- protected override IEnumerable GetVersionFileLocations ()
- {
- yield return Path.GetFullPath (Path.Combine (RuntimePath, "Version"));
- }
- }
-}
-
diff --git a/src/Xamarin.Android.Build.Utilities/Xamarin.Android.Build.Utilities.csproj b/src/Xamarin.Android.Build.Utilities/Xamarin.Android.Build.Utilities.csproj
index da208f36abe..81195b900f5 100644
--- a/src/Xamarin.Android.Build.Utilities/Xamarin.Android.Build.Utilities.csproj
+++ b/src/Xamarin.Android.Build.Utilities/Xamarin.Android.Build.Utilities.csproj
@@ -35,25 +35,14 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ {E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}
+ Xamarin.Android.Tools
+
+