diff --git a/src/Mono.Android/java/mono/android/Runtime.java b/src/Mono.Android/java/mono/android/Runtime.java index ed0cbbf7103..16fcd441cf1 100644 --- a/src/Mono.Android/java/mono/android/Runtime.java +++ b/src/Mono.Android/java/mono/android/Runtime.java @@ -6,7 +6,7 @@ private Runtime () { } - public static native void init (String lang, String[] runtimeApks, String runtimeDataDir, String[] appDirs, ClassLoader loader, String externalStorageDir, String[] assemblies, String packageName); + public static native void init (String lang, String[] runtimeApks, String runtimeDataDir, String[] appDirs, ClassLoader loader, String[] externalStorageDirs, String[] assemblies, String packageName); public static native void register (String managedType, java.lang.Class nativeClass, String methods); public static native void notifyTimeZoneChanged (); public static native int createNewContext (String[] runtimeApks, String[] assemblies, ClassLoader loader); diff --git a/src/Xamarin.Android.Build.Tasks/Resources/MonoPackageManager.api4.java b/src/Xamarin.Android.Build.Tasks/Resources/MonoPackageManager.api4.java index 9ec169cb914..ab92c6aa962 100644 --- a/src/Xamarin.Android.Build.Tasks/Resources/MonoPackageManager.api4.java +++ b/src/Xamarin.Android.Build.Tasks/Resources/MonoPackageManager.api4.java @@ -38,6 +38,13 @@ public static void LoadApplication (Context context, ApplicationInfo runtimePack String cacheDir = context.getCacheDir ().getAbsolutePath (); String dataDir = context.getApplicationInfo ().dataDir + "/lib"; ClassLoader loader = context.getClassLoader (); + java.io.File external0 = android.os.Environment.getExternalStorageDirectory (); + String externalDir = new java.io.File ( + external0, + "Android/data/" + context.getPackageName () + "/files/.__override__").getAbsolutePath (); + String externalLegacyDir = new java.io.File ( + external0, + "../legacy/Android/data/" + context.getPackageName () + "/files/.__override__").getAbsolutePath (); Runtime.init ( language, @@ -49,9 +56,10 @@ public static void LoadApplication (Context context, ApplicationInfo runtimePack dataDir, }, loader, - new java.io.File ( - android.os.Environment.getExternalStorageDirectory (), - "Android/data/" + context.getPackageName () + "/files/.__override__").getAbsolutePath (), + new String[] { + externalDir, + externalLegacyDir + }, MonoPackageManager_Resources.Assemblies, context.getPackageName ()); diff --git a/src/Xamarin.Android.Build.Tasks/Resources/MonoPackageManager.java b/src/Xamarin.Android.Build.Tasks/Resources/MonoPackageManager.java index dd4052bd739..d43792d46de 100644 --- a/src/Xamarin.Android.Build.Tasks/Resources/MonoPackageManager.java +++ b/src/Xamarin.Android.Build.Tasks/Resources/MonoPackageManager.java @@ -38,6 +38,13 @@ public static void LoadApplication (Context context, ApplicationInfo runtimePack String cacheDir = context.getCacheDir ().getAbsolutePath (); String dataDir = getNativeLibraryPath (context); ClassLoader loader = context.getClassLoader (); + java.io.File external0 = android.os.Environment.getExternalStorageDirectory (); + String externalDir = new java.io.File ( + external0, + "Android/data/" + context.getPackageName () + "/files/.__override__").getAbsolutePath (); + String externalLegacyDir = new java.io.File ( + external0, + "../legacy/Android/data/" + context.getPackageName () + "/files/.__override__").getAbsolutePath (); Runtime.init ( language, @@ -49,9 +56,10 @@ public static void LoadApplication (Context context, ApplicationInfo runtimePack dataDir, }, loader, - new java.io.File ( - android.os.Environment.getExternalStorageDirectory (), - "Android/data/" + context.getPackageName () + "/files/.__override__").getAbsolutePath (), + new String[] { + externalDir, + externalLegacyDir + }, MonoPackageManager_Resources.Assemblies, context.getPackageName ()); diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs index 882b4d3f1c9..30fcc1ca399 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs @@ -486,6 +486,8 @@ public void MergeLibraryManifest () android:authorities='${applicationId}.FacebookInitProvider' android:name='.internal.FacebookInitProvider' android:exported='false' /> + + ", encoding: System.Text.Encoding.UTF8); @@ -522,6 +524,8 @@ public void MergeLibraryManifest () "${applicationId}.FacebookInitProvider was not replaced with com.xamarin.manifest.FacebookInitProvider"); Assert.IsTrue (manifest.Contains ("com.xamarin.test.internal.FacebookInitProvider"), ".internal.FacebookInitProvider was not replaced with com.xamarin.test.internal.FacebookInitProvider"); + Assert.AreEqual (manifest.IndexOf ("meta-data", StringComparison.OrdinalIgnoreCase), + manifest.LastIndexOf ("meta-data", StringComparison.OrdinalIgnoreCase), "There should be only one meta-data element"); } } } diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs b/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs index b009cb91338..c16b4ca4ffa 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs @@ -401,6 +401,16 @@ void MergeLibraryManifest (string mergedManifest) } } + void RemoveDuplicateElements () + { + var duplicates = doc.Descendants () + .GroupBy (x => x.ToFullString ()) + .SelectMany (x => x.Skip (1)); + foreach (var duplicate in duplicates) + duplicate.Remove (); + + } + IEnumerable FixupNameElements(string packageName, IEnumerable nodes) { foreach (var element in nodes.Select ( x => x as XElement).Where (x => x != null && ManifestAttributeFixups.ContainsKey (x.Name.LocalName))) { @@ -838,6 +848,7 @@ public void Save (string filename) public void Save (System.IO.TextWriter stream) { + RemoveDuplicateElements (); var ms = new MemoryStream (); doc.Save (ms); ms.Flush (); diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/XDocumentExtensions.cs b/src/Xamarin.Android.Build.Tasks/Utilities/XDocumentExtensions.cs index d05efb5ab68..5bac4ba45a3 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/XDocumentExtensions.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/XDocumentExtensions.cs @@ -22,6 +22,11 @@ public static string[] GetPaths (this XDocument doc, params string[] paths) e = e.Elements (p); return e.Select (p => p.Value).ToArray (); } + + public static string ToFullString (this XElement element) + { + return element.ToString (SaveOptions.DisableFormatting); + } } } diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index 36eabbf3d07..6a891b37b2d 100755 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -279,6 +279,11 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. True + + + True + + False @@ -1025,7 +1030,7 @@ because xbuild doesn't support framework reference assemblies. - + GetObjectArrayElement (env, appDirs, 0)); - esd = (*env)->GetStringUTFChars (env, externalStorageDir, NULL); + esd = (*env)->GetStringUTFChars (env, (*env)->GetObjectArrayElement (env, externalStorageDirs, 0), NULL); external_override_dir = monodroid_strdup_printf ("%s", esd); - (*env)->ReleaseStringUTFChars (env, externalStorageDir, esd); + (*env)->ReleaseStringUTFChars (env, (*env)->GetObjectArrayElement (env, externalStorageDirs, 0), esd); + + esd = (*env)->GetStringUTFChars (env, (*env)->GetObjectArrayElement (env, externalStorageDirs, 1), NULL); + external_legacy_override_dir = monodroid_strdup_printf ("%s", esd); + (*env)->ReleaseStringUTFChars (env, (*env)->GetObjectArrayElement (env, externalStorageDirs, 1), esd); init_categories (primary_override_dir); create_update_dir (primary_override_dir); @@ -3937,6 +3944,7 @@ Java_mono_android_Runtime_init (JNIEnv *env, jclass klass, jstring lang, jobject #ifndef RELEASE override_dirs [1] = external_override_dir; + override_dirs [2] = external_legacy_override_dir; for (i = 0; i < MAX_OVERRIDES; ++i) { const char *p = override_dirs [i]; if (!directory_exists (p))