From 6354dd009428684e13b9b16f7216f1b6570432cc Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 16 Aug 2021 12:51:31 -0400 Subject: [PATCH 01/30] Use a different Personal folder on tvOS, and a test that it works --- .../tests/System/EnvironmentTests.cs | 7 +++++ .../src/System/Environment.iOS.cs | 31 ++++++++++++++----- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs index f019b1eb11a02..7683a60338d9c 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs @@ -330,6 +330,13 @@ public void FailFast_ExceptionStackTrace_InnerException() } } + [Fact] + [PlatformSpecific(TestPlatforms.AnyUnix | TestPlatforms.Browser)] + public void GetFolderPath_Unix_PersonalExists() + { + Assert.True(Directory.Exists(Environment.GetFolderPath(Environment.SpecialFolder.Personal))); + } + [Fact] [PlatformSpecific(TestPlatforms.AnyUnix | TestPlatforms.Browser)] // Tests OS-specific environment public void GetFolderPath_Unix_PersonalIsHomeAndUserProfile() diff --git a/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs b/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs index 1a95bdc408f1c..d984d01022a0a 100644 --- a/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs +++ b/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs @@ -34,20 +34,22 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio private static string? GetSpecialFolder(SpecialFolder folder) { +#if TARGET_TVOS + string DocumentsSearchPath = CombineAndCreateSearchPath(NSSearchPathDirectory.NSLibraryDirectory, Path.Combine("Caches", "Documents")); +#else + string DocumentsSearchPath = Interop.Sys.SearchPath(NSSearchPathDirectory.NSDocumentDirectory); +#endif + switch (folder) { - // TODO: fix for tvOS (https://github.com/dotnet/runtime/issues/34007) - // The "normal" NSDocumentDirectory is a read-only directory on tvOS - // and that breaks a lot of assumptions in the runtime and the BCL - case SpecialFolder.Personal: case SpecialFolder.LocalApplicationData: - return Interop.Sys.SearchPath(NSSearchPathDirectory.NSDocumentDirectory); + return DocumentsSearchPath; case SpecialFolder.ApplicationData: // note: at first glance that looked like a good place to return NSLibraryDirectory // but it would break isolated storage for existing applications - return CombineSearchPath(NSSearchPathDirectory.NSDocumentDirectory, ".config"); + return Path.Combine(DocumentsSearchPath, ".config"); case SpecialFolder.Resources: return Interop.Sys.SearchPath(NSSearchPathDirectory.NSLibraryDirectory); // older (8.2 and previous) would return String.Empty @@ -63,7 +65,7 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio return Path.Combine(GetFolderPathCore(SpecialFolder.Personal, SpecialFolderOption.None), "Pictures"); case SpecialFolder.Templates: - return CombineSearchPath(NSSearchPathDirectory.NSDocumentDirectory, "Templates"); + return Path.Combine(DocumentsSearchPath, "Templates"); case SpecialFolder.MyVideos: return Path.Combine(GetFolderPathCore(SpecialFolder.Personal, SpecialFolderOption.None), "Videos"); @@ -72,7 +74,7 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio return "/usr/share/templates"; case SpecialFolder.Fonts: - return CombineSearchPath(NSSearchPathDirectory.NSDocumentDirectory, ".fonts"); + return Path.Combine(DocumentsSearchPath, ".fonts"); case SpecialFolder.Favorites: return CombineSearchPath(NSSearchPathDirectory.NSLibraryDirectory, "Favorites"); @@ -100,6 +102,19 @@ static string CombineSearchPath(NSSearchPathDirectory searchPath, string subdire Path.Combine(path, subdirectory) : string.Empty; } + + // Special version of CombineSearchPath which creates the path if needed. + // This isn't needed for "real" search paths which always exist, but on tvOS + // the base path is really a subdirectory we define rather than an OS directory. + // In order to not treat Directory.Exists(SpecialFolder.ApplicationData) differently + // on tvOS, guarantee that it exists by creating it here + static string CombineAndCreateSearchPath(NSSearchPathDirectory searchPath, string subdirectory) + { + string path = CombineSearchPath(searchPath, subdirectory); + if (!Directory.Exists (path)) + Directory.CreateDirectory (path); + return path; + } } } } From 0ee7a715d061211a5ecd11fd9731f3c243ddc1a2 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 16 Aug 2021 12:52:23 -0400 Subject: [PATCH 02/30] Run this PR on device, the error does not happen on sim --- eng/pipelines/runtime.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 0fca635b79398..d408ae3c92274 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -228,6 +228,7 @@ jobs: - MacCatalyst_x64 - MacCatalyst_arm64 - tvOSSimulator_x64 + - tvOS_arm64 - iOSSimulator_x86 - iOS_arm64 - Linux_arm From 5854dfc5132ad8900a63574bad81b26df1e96907 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 16 Aug 2021 13:49:49 -0400 Subject: [PATCH 03/30] CI fixes --- .../System.Private.CoreLib/src/System/Environment.iOS.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs b/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs index d984d01022a0a..817030dcc792f 100644 --- a/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs +++ b/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs @@ -35,9 +35,9 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio private static string? GetSpecialFolder(SpecialFolder folder) { #if TARGET_TVOS - string DocumentsSearchPath = CombineAndCreateSearchPath(NSSearchPathDirectory.NSLibraryDirectory, Path.Combine("Caches", "Documents")); + string? DocumentsSearchPath = CombineAndCreateSearchPath(NSSearchPathDirectory.NSLibraryDirectory, Path.Combine("Caches", "Documents")); #else - string DocumentsSearchPath = Interop.Sys.SearchPath(NSSearchPathDirectory.NSDocumentDirectory); + string? DocumentsSearchPath = Interop.Sys.SearchPath(NSSearchPathDirectory.NSDocumentDirectory); #endif switch (folder) @@ -103,6 +103,7 @@ static string CombineSearchPath(NSSearchPathDirectory searchPath, string subdire string.Empty; } +#if TARGET_TVOS // Special version of CombineSearchPath which creates the path if needed. // This isn't needed for "real" search paths which always exist, but on tvOS // the base path is really a subdirectory we define rather than an OS directory. @@ -115,6 +116,7 @@ static string CombineAndCreateSearchPath(NSSearchPathDirectory searchPath, strin Directory.CreateDirectory (path); return path; } +#endif } } } From 7473c19df3ebd5c053ad3d4b50222f7778c6c10a Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 16 Aug 2021 16:02:01 -0400 Subject: [PATCH 04/30] Nullable --- .../System.Private.CoreLib/src/System/Environment.iOS.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs b/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs index 817030dcc792f..077b72f797223 100644 --- a/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs +++ b/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs @@ -49,7 +49,7 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio case SpecialFolder.ApplicationData: // note: at first glance that looked like a good place to return NSLibraryDirectory // but it would break isolated storage for existing applications - return Path.Combine(DocumentsSearchPath, ".config"); + return DocumentsSearchPath != null ? Path.Combine(DocumentsSearchPath, ".config") : string.Empty; case SpecialFolder.Resources: return Interop.Sys.SearchPath(NSSearchPathDirectory.NSLibraryDirectory); // older (8.2 and previous) would return String.Empty @@ -65,7 +65,7 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio return Path.Combine(GetFolderPathCore(SpecialFolder.Personal, SpecialFolderOption.None), "Pictures"); case SpecialFolder.Templates: - return Path.Combine(DocumentsSearchPath, "Templates"); + return DocumentsSearchPath != null ? Path.Combine(DocumentsSearchPath, "Templates") : string.Empty; case SpecialFolder.MyVideos: return Path.Combine(GetFolderPathCore(SpecialFolder.Personal, SpecialFolderOption.None), "Videos"); @@ -74,7 +74,7 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio return "/usr/share/templates"; case SpecialFolder.Fonts: - return Path.Combine(DocumentsSearchPath, ".fonts"); + return DocumentsSearchPath != null ? Path.Combine(DocumentsSearchPath, ".fonts") : string.Empty; case SpecialFolder.Favorites: return CombineSearchPath(NSSearchPathDirectory.NSLibraryDirectory, "Favorites"); From 877258fb866b8db57ee20b9c8c5fa94fea46c956 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 16 Aug 2021 16:18:01 -0400 Subject: [PATCH 05/30] Test on devices --- eng/pipelines/runtime-staging.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/eng/pipelines/runtime-staging.yml b/eng/pipelines/runtime-staging.yml index 40ca5bf9b2fab..3362d42d8f435 100644 --- a/eng/pipelines/runtime-staging.yml +++ b/eng/pipelines/runtime-staging.yml @@ -68,6 +68,7 @@ jobs: - MacCatalyst_x64 - iOSSimulator_x64 - tvOSSimulator_x64 + - tvOS_arm64 # don't run tests on arm64 PRs until we can get significantly more devices - ${{ if eq(variables['isFullMatrix'], true) }}: - MacCatalyst_arm64 From b032fc0ee0462fd30862a6b56006d71d95f32216 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 16 Aug 2021 19:57:41 -0400 Subject: [PATCH 06/30] Just run one test to save disk space --- src/libraries/tests.proj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 5e8f9b5cf4ff4..8393634631fcf 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -298,7 +298,7 @@ - Date: Mon, 16 Aug 2021 23:05:38 -0400 Subject: [PATCH 07/30] Tweak to run only 1 test and make sure DevTeamProvisioning is right --- eng/testing/tests.mobile.targets | 1 + src/libraries/tests.proj | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index 0cb9a22a4b6cd..263cee434d8d2 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -142,6 +142,7 @@ adhoc + - diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 8393634631fcf..057060743cb9d 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -170,7 +170,7 @@ - + @@ -300,7 +300,10 @@ + Condition="'$(TargetOS)' == 'tvOS' and '$(TestAssemblies)' == 'true'" /> + - + + + + + From a39e472af8071fc91936d5e3bae10d328164500e Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Tue, 17 Aug 2021 15:56:26 -0400 Subject: [PATCH 08/30] Horrible hack to check something in CI --- .../System.Private.CoreLib/src/System/Environment.iOS.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs b/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs index 077b72f797223..d27b8a08823ff 100644 --- a/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs +++ b/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs @@ -112,8 +112,9 @@ static string CombineSearchPath(NSSearchPathDirectory searchPath, string subdire static string CombineAndCreateSearchPath(NSSearchPathDirectory searchPath, string subdirectory) { string path = CombineSearchPath(searchPath, subdirectory); - if (!Directory.Exists (path)) - Directory.CreateDirectory (path); +// DISABLE FOR NOW FOR DEBUGGING +// if (!Directory.Exists (path)) +// Directory.CreateDirectory (path); return path; } #endif From cfcb6dc2415c7526175def8f65bfc4f39f0c063a Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Tue, 17 Aug 2021 18:33:38 -0400 Subject: [PATCH 09/30] Revert all changes. Run as-is in CI to see if it's my changes to blame --- .../src/System/Environment.iOS.cs | 34 +++++-------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs b/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs index d27b8a08823ff..1a95bdc408f1c 100644 --- a/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs +++ b/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs @@ -34,22 +34,20 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio private static string? GetSpecialFolder(SpecialFolder folder) { -#if TARGET_TVOS - string? DocumentsSearchPath = CombineAndCreateSearchPath(NSSearchPathDirectory.NSLibraryDirectory, Path.Combine("Caches", "Documents")); -#else - string? DocumentsSearchPath = Interop.Sys.SearchPath(NSSearchPathDirectory.NSDocumentDirectory); -#endif - switch (folder) { + // TODO: fix for tvOS (https://github.com/dotnet/runtime/issues/34007) + // The "normal" NSDocumentDirectory is a read-only directory on tvOS + // and that breaks a lot of assumptions in the runtime and the BCL + case SpecialFolder.Personal: case SpecialFolder.LocalApplicationData: - return DocumentsSearchPath; + return Interop.Sys.SearchPath(NSSearchPathDirectory.NSDocumentDirectory); case SpecialFolder.ApplicationData: // note: at first glance that looked like a good place to return NSLibraryDirectory // but it would break isolated storage for existing applications - return DocumentsSearchPath != null ? Path.Combine(DocumentsSearchPath, ".config") : string.Empty; + return CombineSearchPath(NSSearchPathDirectory.NSDocumentDirectory, ".config"); case SpecialFolder.Resources: return Interop.Sys.SearchPath(NSSearchPathDirectory.NSLibraryDirectory); // older (8.2 and previous) would return String.Empty @@ -65,7 +63,7 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio return Path.Combine(GetFolderPathCore(SpecialFolder.Personal, SpecialFolderOption.None), "Pictures"); case SpecialFolder.Templates: - return DocumentsSearchPath != null ? Path.Combine(DocumentsSearchPath, "Templates") : string.Empty; + return CombineSearchPath(NSSearchPathDirectory.NSDocumentDirectory, "Templates"); case SpecialFolder.MyVideos: return Path.Combine(GetFolderPathCore(SpecialFolder.Personal, SpecialFolderOption.None), "Videos"); @@ -74,7 +72,7 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio return "/usr/share/templates"; case SpecialFolder.Fonts: - return DocumentsSearchPath != null ? Path.Combine(DocumentsSearchPath, ".fonts") : string.Empty; + return CombineSearchPath(NSSearchPathDirectory.NSDocumentDirectory, ".fonts"); case SpecialFolder.Favorites: return CombineSearchPath(NSSearchPathDirectory.NSLibraryDirectory, "Favorites"); @@ -102,22 +100,6 @@ static string CombineSearchPath(NSSearchPathDirectory searchPath, string subdire Path.Combine(path, subdirectory) : string.Empty; } - -#if TARGET_TVOS - // Special version of CombineSearchPath which creates the path if needed. - // This isn't needed for "real" search paths which always exist, but on tvOS - // the base path is really a subdirectory we define rather than an OS directory. - // In order to not treat Directory.Exists(SpecialFolder.ApplicationData) differently - // on tvOS, guarantee that it exists by creating it here - static string CombineAndCreateSearchPath(NSSearchPathDirectory searchPath, string subdirectory) - { - string path = CombineSearchPath(searchPath, subdirectory); -// DISABLE FOR NOW FOR DEBUGGING -// if (!Directory.Exists (path)) -// Directory.CreateDirectory (path); - return path; - } -#endif } } } From c50a1af0cb1578a08f3bcf13ee1fc40030618747 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Tue, 17 Aug 2021 19:56:30 -0400 Subject: [PATCH 10/30] nonsense --- eng/pipelines/runtime-staging.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/eng/pipelines/runtime-staging.yml b/eng/pipelines/runtime-staging.yml index 3362d42d8f435..1b33abc50cf6c 100644 --- a/eng/pipelines/runtime-staging.yml +++ b/eng/pipelines/runtime-staging.yml @@ -69,6 +69,7 @@ jobs: - iOSSimulator_x64 - tvOSSimulator_x64 - tvOS_arm64 + #adding noise to force a rebuild # don't run tests on arm64 PRs until we can get significantly more devices - ${{ if eq(variables['isFullMatrix'], true) }}: - MacCatalyst_arm64 From 7e7d49bd34869c9284af52365c895a49f1d98d42 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Wed, 18 Aug 2021 00:18:57 -0400 Subject: [PATCH 11/30] Set temp path to a valid location --- eng/pipelines/runtime-staging.yml | 1 - .../System/IO/FileCleanupTestBase.cs | 5 ++- .../TestUtilities/System/PlatformDetection.cs | 2 ++ .../src/System/Environment.iOS.cs | 33 ++++++++++++++----- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/eng/pipelines/runtime-staging.yml b/eng/pipelines/runtime-staging.yml index 1b33abc50cf6c..3362d42d8f435 100644 --- a/eng/pipelines/runtime-staging.yml +++ b/eng/pipelines/runtime-staging.yml @@ -69,7 +69,6 @@ jobs: - iOSSimulator_x64 - tvOSSimulator_x64 - tvOS_arm64 - #adding noise to force a rebuild # don't run tests on arm64 PRs until we can get significantly more devices - ${{ if eq(variables['isFullMatrix'], true) }}: - MacCatalyst_arm64 diff --git a/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs b/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs index 04b27885d4d38..4c2f1f9f56ba0 100644 --- a/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs +++ b/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using Xunit; +using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Threading; @@ -20,8 +21,10 @@ public abstract class FileCleanupTestBase : IDisposable /// Initialize the test class base. This creates the associated test directory. protected FileCleanupTestBase(string tempDirectory = null) { - tempDirectory ??= Path.GetTempPath(); + // Question - should we relocate Path.GetTempPath on iOS/tvOS to something that is going to work? + tempDirectory ??= PlatformDetection.IsNotAppleMobile ? Path.GetTempPath() : Environment.GetFolderPath(Environment.SpecialFolder.InternetCache); + Console.WriteLine("Temp Directory: " + tempDirectory); // Use a unique test directory per test class. The test directory lives in the user's temp directory, // and includes both the name of the test class and a random string. The test class name is included // so that it can be easily correlated if necessary, and the random string to helps avoid conflicts if diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index efef067dbce64..6425916da32aa 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -40,6 +40,8 @@ public static partial class PlatformDetection public static bool IsNotBrowser => !IsBrowser; public static bool IsMobile => IsBrowser || IsMacCatalyst || IsiOS || IstvOS || IsAndroid; public static bool IsNotMobile => !IsMobile; + public static bool IsAppleMobile => IsMacCatalyst || IsiOS || IstvOS; + public static bool IsNotAppleMobile => !IsAppleMobile; public static bool IsNotNetFramework => !IsNetFramework; public static bool IsArmProcess => RuntimeInformation.ProcessArchitecture == Architecture.Arm; diff --git a/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs b/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs index 1a95bdc408f1c..077b72f797223 100644 --- a/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs +++ b/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs @@ -34,20 +34,22 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio private static string? GetSpecialFolder(SpecialFolder folder) { +#if TARGET_TVOS + string? DocumentsSearchPath = CombineAndCreateSearchPath(NSSearchPathDirectory.NSLibraryDirectory, Path.Combine("Caches", "Documents")); +#else + string? DocumentsSearchPath = Interop.Sys.SearchPath(NSSearchPathDirectory.NSDocumentDirectory); +#endif + switch (folder) { - // TODO: fix for tvOS (https://github.com/dotnet/runtime/issues/34007) - // The "normal" NSDocumentDirectory is a read-only directory on tvOS - // and that breaks a lot of assumptions in the runtime and the BCL - case SpecialFolder.Personal: case SpecialFolder.LocalApplicationData: - return Interop.Sys.SearchPath(NSSearchPathDirectory.NSDocumentDirectory); + return DocumentsSearchPath; case SpecialFolder.ApplicationData: // note: at first glance that looked like a good place to return NSLibraryDirectory // but it would break isolated storage for existing applications - return CombineSearchPath(NSSearchPathDirectory.NSDocumentDirectory, ".config"); + return DocumentsSearchPath != null ? Path.Combine(DocumentsSearchPath, ".config") : string.Empty; case SpecialFolder.Resources: return Interop.Sys.SearchPath(NSSearchPathDirectory.NSLibraryDirectory); // older (8.2 and previous) would return String.Empty @@ -63,7 +65,7 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio return Path.Combine(GetFolderPathCore(SpecialFolder.Personal, SpecialFolderOption.None), "Pictures"); case SpecialFolder.Templates: - return CombineSearchPath(NSSearchPathDirectory.NSDocumentDirectory, "Templates"); + return DocumentsSearchPath != null ? Path.Combine(DocumentsSearchPath, "Templates") : string.Empty; case SpecialFolder.MyVideos: return Path.Combine(GetFolderPathCore(SpecialFolder.Personal, SpecialFolderOption.None), "Videos"); @@ -72,7 +74,7 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio return "/usr/share/templates"; case SpecialFolder.Fonts: - return CombineSearchPath(NSSearchPathDirectory.NSDocumentDirectory, ".fonts"); + return DocumentsSearchPath != null ? Path.Combine(DocumentsSearchPath, ".fonts") : string.Empty; case SpecialFolder.Favorites: return CombineSearchPath(NSSearchPathDirectory.NSLibraryDirectory, "Favorites"); @@ -100,6 +102,21 @@ static string CombineSearchPath(NSSearchPathDirectory searchPath, string subdire Path.Combine(path, subdirectory) : string.Empty; } + +#if TARGET_TVOS + // Special version of CombineSearchPath which creates the path if needed. + // This isn't needed for "real" search paths which always exist, but on tvOS + // the base path is really a subdirectory we define rather than an OS directory. + // In order to not treat Directory.Exists(SpecialFolder.ApplicationData) differently + // on tvOS, guarantee that it exists by creating it here + static string CombineAndCreateSearchPath(NSSearchPathDirectory searchPath, string subdirectory) + { + string path = CombineSearchPath(searchPath, subdirectory); + if (!Directory.Exists (path)) + Directory.CreateDirectory (path); + return path; + } +#endif } } } From 064670d01d206edfc7b08f64003fb09478248d71 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Wed, 18 Aug 2021 01:55:24 -0400 Subject: [PATCH 12/30] Fix AppDomainTests.ExecuteAssembly to copy files to a valid place --- .../tests/TestUtilities/System/IO/FileCleanupTestBase.cs | 1 - .../tests/System/AppDomainTests.cs | 6 ++++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs b/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs index 4c2f1f9f56ba0..7fd38472123c2 100644 --- a/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs +++ b/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs @@ -24,7 +24,6 @@ protected FileCleanupTestBase(string tempDirectory = null) // Question - should we relocate Path.GetTempPath on iOS/tvOS to something that is going to work? tempDirectory ??= PlatformDetection.IsNotAppleMobile ? Path.GetTempPath() : Environment.GetFolderPath(Environment.SpecialFolder.InternetCache); - Console.WriteLine("Temp Directory: " + tempDirectory); // Use a unique test directory per test class. The test directory lives in the user's temp directory, // and includes both the name of the test class and a random string. The test class name is included // so that it can be easily correlated if necessary, and the random string to helps avoid conflicts if diff --git a/src/libraries/System.Runtime.Extensions/tests/System/AppDomainTests.cs b/src/libraries/System.Runtime.Extensions/tests/System/AppDomainTests.cs index e9fe758b834f7..1ea1ed76ab581 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/AppDomainTests.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/AppDomainTests.cs @@ -763,14 +763,16 @@ public void SetThreadPrincipal() private void CopyTestAssemblies() { - string destTestAssemblyPath = Path.Combine(Environment.CurrentDirectory, "AssemblyResolveTestApp", "AssemblyResolveTestApp.dll"); + string curDirectory = PlatformDetection.IsNotAppleMobile ? Environment.CurrentDirectory : Environment.GetFolderPath(Environment.SpecialFolder.InternetCache); + + string destTestAssemblyPath = Path.Combine(curDirectory, "AssemblyResolveTestApp", "AssemblyResolveTestApp.dll"); if (!File.Exists(destTestAssemblyPath) && File.Exists("AssemblyResolveTestApp.dll")) { Directory.CreateDirectory(Path.GetDirectoryName(destTestAssemblyPath)); File.Copy("AssemblyResolveTestApp.dll", destTestAssemblyPath, false); } - destTestAssemblyPath = Path.Combine(Environment.CurrentDirectory, "TestAppOutsideOfTPA", "TestAppOutsideOfTPA.exe"); + destTestAssemblyPath = Path.Combine(curDirectory, "TestAppOutsideOfTPA", "TestAppOutsideOfTPA.exe"); if (!File.Exists(destTestAssemblyPath) && File.Exists("TestAppOutsideOfTPA.exe")) { Directory.CreateDirectory(Path.GetDirectoryName(destTestAssemblyPath)); From a48cfe798463053ce0696a6ebc14ce5801991557 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Wed, 18 Aug 2021 09:02:54 -0400 Subject: [PATCH 13/30] Don't expect HOME to work on tvOS --- .../tests/System/EnvironmentTests.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs index 7683a60338d9c..f2b35eb6c2cdf 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs @@ -346,7 +346,11 @@ public void GetFolderPath_Unix_PersonalIsHomeAndUserProfile() Assert.Equal(Environment.GetEnvironmentVariable("HOME"), Environment.GetFolderPath(Environment.SpecialFolder.Personal)); Assert.Equal(Environment.GetEnvironmentVariable("HOME"), Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)); } - Assert.Equal(Environment.GetEnvironmentVariable("HOME"), Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)); + // tvOS effectively doesn't have a HOME + if (!PlatformDetection.IstvOS) + { + Assert.Equal(Environment.GetEnvironmentVariable("HOME"), Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)); + } } [Theory] From 26354d748018c4c96214a79e260c11d287b81af2 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Wed, 18 Aug 2021 09:06:34 -0400 Subject: [PATCH 14/30] We cannot get exit code from tvOS device, so runonly tests don't work --- src/libraries/sendtohelixhelp.proj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/sendtohelixhelp.proj b/src/libraries/sendtohelixhelp.proj index b106d310e0276..ed303b80890cc 100644 --- a/src/libraries/sendtohelixhelp.proj +++ b/src/libraries/sendtohelixhelp.proj @@ -292,7 +292,7 @@ $(AppleTestTarget) - + false From 4ee0555967648be55abfdc298d7d01e20c687219 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Wed, 18 Aug 2021 10:02:10 -0400 Subject: [PATCH 15/30] Revert infra changes made to enable CI of this PR, which passes now on device --- eng/pipelines/runtime-staging.yml | 1 - eng/pipelines/runtime.yml | 1 - eng/testing/tests.mobile.targets | 1 - src/libraries/tests.proj | 22 +++------------------- 4 files changed, 3 insertions(+), 22 deletions(-) diff --git a/eng/pipelines/runtime-staging.yml b/eng/pipelines/runtime-staging.yml index 3362d42d8f435..40ca5bf9b2fab 100644 --- a/eng/pipelines/runtime-staging.yml +++ b/eng/pipelines/runtime-staging.yml @@ -68,7 +68,6 @@ jobs: - MacCatalyst_x64 - iOSSimulator_x64 - tvOSSimulator_x64 - - tvOS_arm64 # don't run tests on arm64 PRs until we can get significantly more devices - ${{ if eq(variables['isFullMatrix'], true) }}: - MacCatalyst_arm64 diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index d408ae3c92274..0fca635b79398 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -228,7 +228,6 @@ jobs: - MacCatalyst_x64 - MacCatalyst_arm64 - tvOSSimulator_x64 - - tvOS_arm64 - iOSSimulator_x86 - iOS_arm64 - Linux_arm diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index 263cee434d8d2..0cb9a22a4b6cd 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -142,7 +142,6 @@ adhoc - - diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 057060743cb9d..1aac4ed657d29 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -170,7 +170,7 @@ - + @@ -240,15 +240,8 @@ - - - - - - - @@ -298,12 +291,9 @@ - + Condition="'$(TestAssemblies)' == 'true'" /> - + - - - - From 07660e2c56276d6c9ec1d5a32117e9cb41afe602 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Wed, 18 Aug 2021 17:37:34 -0400 Subject: [PATCH 16/30] Add NSTemporaryDirectory interop function and supporting cast --- .../System.Native/Interop.SearchPath.iOS.cs | 14 +++++++++++++ .../System/IO/FileCleanupTestBase.cs | 4 ++-- .../Native/Unix/System.Native/entrypoints.c | 1 + .../Unix/System.Native/pal_searchpath.c | 6 ++++++ .../Unix/System.Native/pal_searchpath.h | 2 ++ .../Unix/System.Native/pal_searchpath.m | 7 +++++++ .../System.Private.CoreLib.Shared.projitems | 2 ++ .../src/System/IO/Path.Unix.NoniOS.cs | 10 +++++++++ .../src/System/IO/Path.Unix.cs | 3 +-- .../src/System/IO/Path.Unix.iOS.cs | 21 +++++++++++++++++++ .../System.Private.CoreLib.csproj | 3 +++ 11 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 src/libraries/Common/src/Interop/OSX/System.Native/Interop.SearchPath.iOS.cs create mode 100644 src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.NoniOS.cs create mode 100644 src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs diff --git a/src/libraries/Common/src/Interop/OSX/System.Native/Interop.SearchPath.iOS.cs b/src/libraries/Common/src/Interop/OSX/System.Native/Interop.SearchPath.iOS.cs new file mode 100644 index 0000000000000..0e5ea9b78e72f --- /dev/null +++ b/src/libraries/Common/src/Interop/OSX/System.Native/Interop.SearchPath.iOS.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Sys + { + [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_SearchPath_TempDirectory")] + internal static extern string? SearchPathTempDirectory(); + } +} diff --git a/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs b/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs index 7fd38472123c2..0b7c42d23bd63 100644 --- a/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs +++ b/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs @@ -21,8 +21,8 @@ public abstract class FileCleanupTestBase : IDisposable /// Initialize the test class base. This creates the associated test directory. protected FileCleanupTestBase(string tempDirectory = null) { - // Question - should we relocate Path.GetTempPath on iOS/tvOS to something that is going to work? - tempDirectory ??= PlatformDetection.IsNotAppleMobile ? Path.GetTempPath() : Environment.GetFolderPath(Environment.SpecialFolder.InternetCache); + //tempDirectory ??= PlatformDetection.IsNotAppleMobile ? Path.GetTempPath() : Environment.GetFolderPath(Environment.SpecialFolder.InternetCache); + tempDirectory ??= Path.GetTempPath(); // Use a unique test directory per test class. The test directory lives in the user's temp directory, // and includes both the name of the test class and a random string. The test class name is included diff --git a/src/libraries/Native/Unix/System.Native/entrypoints.c b/src/libraries/Native/Unix/System.Native/entrypoints.c index c8b678ec08340..b3ae64f96f91e 100644 --- a/src/libraries/Native/Unix/System.Native/entrypoints.c +++ b/src/libraries/Native/Unix/System.Native/entrypoints.c @@ -218,6 +218,7 @@ static const Entry s_sysNative[] = DllImportEntry(SystemNative_GetOSArchitecture) DllImportEntry(SystemNative_GetProcessArchitecture) DllImportEntry(SystemNative_SearchPath) + DllImportEntry(SystemNative_SearchPath_TempDirectory) DllImportEntry(SystemNative_RegisterForSigChld) DllImportEntry(SystemNative_SetDelayedSigChildConsoleConfigurationHandler) DllImportEntry(SystemNative_SetTerminalInvalidationHandler) diff --git a/src/libraries/Native/Unix/System.Native/pal_searchpath.c b/src/libraries/Native/Unix/System.Native/pal_searchpath.c index fbf3d903df01c..de8037dc1a295 100644 --- a/src/libraries/Native/Unix/System.Native/pal_searchpath.c +++ b/src/libraries/Native/Unix/System.Native/pal_searchpath.c @@ -10,3 +10,9 @@ const char* SystemNative_SearchPath(int32_t folderId) __builtin_unreachable(); return NULL; } + +const char* SystemNative_SearchPath_TempDirectory() +{ + __builtin_unreachable(); + return NULL; +} diff --git a/src/libraries/Native/Unix/System.Native/pal_searchpath.h b/src/libraries/Native/Unix/System.Native/pal_searchpath.h index e2de05d8c8860..1dedc09852184 100644 --- a/src/libraries/Native/Unix/System.Native/pal_searchpath.h +++ b/src/libraries/Native/Unix/System.Native/pal_searchpath.h @@ -7,3 +7,5 @@ #include "pal_types.h" PALEXPORT const char* SystemNative_SearchPath(int32_t folderId); + +PALEXPORT const char* SystemNative_SearchPath_TempDirectory(); diff --git a/src/libraries/Native/Unix/System.Native/pal_searchpath.m b/src/libraries/Native/Unix/System.Native/pal_searchpath.m index 2e96041f3dda8..4f8510b2e8c49 100644 --- a/src/libraries/Native/Unix/System.Native/pal_searchpath.m +++ b/src/libraries/Native/Unix/System.Native/pal_searchpath.m @@ -11,3 +11,10 @@ const char* path = [[url path] UTF8String]; return path == NULL ? NULL : strdup (path); } + +const char* SystemNative_SearchPath_TempDirectory() +{ + NSString* iosPath = NSTemporaryDirectory(); + const char *path = [iosPath UTF8String]; + return path == NULL ? NULL : strdup (path); +} diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 5a1593f032c69..e72c543d58080 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -2112,6 +2112,8 @@ + + diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.NoniOS.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.NoniOS.cs new file mode 100644 index 0000000000000..85aed33038283 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.NoniOS.cs @@ -0,0 +1,10 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.IO +{ + public static partial class Path + { + private static string? DefaultTempPath => "/tmp/"; + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.cs index 61786ad757a43..45e587f6d371f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.cs @@ -80,14 +80,13 @@ private static string RemoveLongPathPrefix(string path) public static string GetTempPath() { const string TempEnvVar = "TMPDIR"; - const string DefaultTempPath = "/tmp/"; // Get the temp path from the TMPDIR environment variable. // If it's not set, just return the default path. // If it is, return it, ensuring it ends with a slash. string? path = Environment.GetEnvironmentVariable(TempEnvVar); return - string.IsNullOrEmpty(path) ? DefaultTempPath : + string.IsNullOrEmpty(path) ? DefaultTempPath! : PathInternal.IsDirectorySeparator(path[path.Length - 1]) ? path : path + PathInternal.DirectorySeparatorChar; } diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs new file mode 100644 index 0000000000000..a52b0070aede4 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace System.IO +{ + public static partial class Path + { + private static string? s_defaultTempPath; + + private static string? DefaultTempPath + { + get + { + s_defaultTempPath ??= Interop.Sys.SearchPathTempDirectory()!; + return s_defaultTempPath!; + } + } + } +} diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj index 1878cb4ed7c05..7aa4413aad70d 100644 --- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -271,6 +271,9 @@ Common\Interop\OSX\Interop.SearchPath.cs + + Common\Interop\OSX\Interop.SearchPath.iOS.cs + From 4b49b07c629af5a93e79ae8740afb9fba31a49ce Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Wed, 18 Aug 2021 23:16:33 -0400 Subject: [PATCH 17/30] forgot a void --- src/libraries/Native/Unix/System.Native/pal_searchpath.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Native/Unix/System.Native/pal_searchpath.h b/src/libraries/Native/Unix/System.Native/pal_searchpath.h index 1dedc09852184..cdb872914624c 100644 --- a/src/libraries/Native/Unix/System.Native/pal_searchpath.h +++ b/src/libraries/Native/Unix/System.Native/pal_searchpath.h @@ -8,4 +8,4 @@ PALEXPORT const char* SystemNative_SearchPath(int32_t folderId); -PALEXPORT const char* SystemNative_SearchPath_TempDirectory(); +PALEXPORT const char* SystemNative_SearchPath_TempDirectory(void); From 84609fcace543b319f44443a1f7facca981ba868 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Thu, 19 Aug 2021 16:24:48 -0400 Subject: [PATCH 18/30] Requested changes from Alex --- .../System/IO/FileCleanupTestBase.cs | 2 -- .../Unix/System.Native/pal_searchpath.m | 4 +-- .../src/System/Environment.iOS.cs | 34 ++++++++----------- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs b/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs index 0b7c42d23bd63..04b27885d4d38 100644 --- a/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs +++ b/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Xunit; -using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Threading; @@ -21,7 +20,6 @@ public abstract class FileCleanupTestBase : IDisposable /// Initialize the test class base. This creates the associated test directory. protected FileCleanupTestBase(string tempDirectory = null) { - //tempDirectory ??= PlatformDetection.IsNotAppleMobile ? Path.GetTempPath() : Environment.GetFolderPath(Environment.SpecialFolder.InternetCache); tempDirectory ??= Path.GetTempPath(); // Use a unique test directory per test class. The test directory lives in the user's temp directory, diff --git a/src/libraries/Native/Unix/System.Native/pal_searchpath.m b/src/libraries/Native/Unix/System.Native/pal_searchpath.m index 4f8510b2e8c49..231c508c527ca 100644 --- a/src/libraries/Native/Unix/System.Native/pal_searchpath.m +++ b/src/libraries/Native/Unix/System.Native/pal_searchpath.m @@ -14,7 +14,7 @@ const char* SystemNative_SearchPath_TempDirectory() { - NSString* iosPath = NSTemporaryDirectory(); - const char *path = [iosPath UTF8String]; + NSString* tempPath = NSTemporaryDirectory(); + const char *path = [tempPath UTF8String]; return path == NULL ? NULL : strdup (path); } diff --git a/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs b/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs index 077b72f797223..01ceb05bba7dc 100644 --- a/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs +++ b/src/mono/System.Private.CoreLib/src/System/Environment.iOS.cs @@ -34,22 +34,16 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio private static string? GetSpecialFolder(SpecialFolder folder) { -#if TARGET_TVOS - string? DocumentsSearchPath = CombineAndCreateSearchPath(NSSearchPathDirectory.NSLibraryDirectory, Path.Combine("Caches", "Documents")); -#else - string? DocumentsSearchPath = Interop.Sys.SearchPath(NSSearchPathDirectory.NSDocumentDirectory); -#endif - switch (folder) { case SpecialFolder.Personal: case SpecialFolder.LocalApplicationData: - return DocumentsSearchPath; + return CombineDocumentDirectory(string.Empty); case SpecialFolder.ApplicationData: // note: at first glance that looked like a good place to return NSLibraryDirectory // but it would break isolated storage for existing applications - return DocumentsSearchPath != null ? Path.Combine(DocumentsSearchPath, ".config") : string.Empty; + return CombineDocumentDirectory(".config"); case SpecialFolder.Resources: return Interop.Sys.SearchPath(NSSearchPathDirectory.NSLibraryDirectory); // older (8.2 and previous) would return String.Empty @@ -65,7 +59,7 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio return Path.Combine(GetFolderPathCore(SpecialFolder.Personal, SpecialFolderOption.None), "Pictures"); case SpecialFolder.Templates: - return DocumentsSearchPath != null ? Path.Combine(DocumentsSearchPath, "Templates") : string.Empty; + return CombineDocumentDirectory("Templates"); case SpecialFolder.MyVideos: return Path.Combine(GetFolderPathCore(SpecialFolder.Personal, SpecialFolderOption.None), "Videos"); @@ -74,7 +68,7 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio return "/usr/share/templates"; case SpecialFolder.Fonts: - return DocumentsSearchPath != null ? Path.Combine(DocumentsSearchPath, ".fonts") : string.Empty; + return CombineDocumentDirectory(".fonts"); case SpecialFolder.Favorites: return CombineSearchPath(NSSearchPathDirectory.NSLibraryDirectory, "Favorites"); @@ -103,20 +97,22 @@ static string CombineSearchPath(NSSearchPathDirectory searchPath, string subdire string.Empty; } -#if TARGET_TVOS - // Special version of CombineSearchPath which creates the path if needed. - // This isn't needed for "real" search paths which always exist, but on tvOS - // the base path is really a subdirectory we define rather than an OS directory. - // In order to not treat Directory.Exists(SpecialFolder.ApplicationData) differently - // on tvOS, guarantee that it exists by creating it here - static string CombineAndCreateSearchPath(NSSearchPathDirectory searchPath, string subdirectory) + static string CombineDocumentDirectory(string subdirectory) { - string path = CombineSearchPath(searchPath, subdirectory); +#if TARGET_TVOS + string? path = CombineSearchPath(NSSearchPathDirectory.NSLibraryDirectory, Path.Combine("Caches", "Documents", subdirectory)); + // Special version of CombineSearchPath which creates the path if needed. + // This isn't needed for "real" search paths which always exist, but on tvOS + // the base path is really a subdirectory we define rather than an OS directory. + // In order to not treat Directory.Exists(SpecialFolder.ApplicationData) differently + // on tvOS, guarantee that it exists by creating it here if (!Directory.Exists (path)) Directory.CreateDirectory (path); +#else + string? path = CombineSearchPath(NSSearchPathDirectory.NSDocumentDirectory, subdirectory); +#endif return path; } -#endif } } } From 9ebb6b0f9ad3f438c4e122fb43c4da5216d1cc87 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 23 Aug 2021 09:34:29 -0400 Subject: [PATCH 19/30] Don't use nullable --- .../Interop/OSX/System.Native/Interop.SearchPath.iOS.cs | 2 +- .../src/System/IO/Path.Unix.NoniOS.cs | 2 +- .../System.Private.CoreLib/src/System/IO/Path.Unix.cs | 2 +- .../System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs | 8 +++++--- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/libraries/Common/src/Interop/OSX/System.Native/Interop.SearchPath.iOS.cs b/src/libraries/Common/src/Interop/OSX/System.Native/Interop.SearchPath.iOS.cs index 0e5ea9b78e72f..8d73184ca4d50 100644 --- a/src/libraries/Common/src/Interop/OSX/System.Native/Interop.SearchPath.iOS.cs +++ b/src/libraries/Common/src/Interop/OSX/System.Native/Interop.SearchPath.iOS.cs @@ -9,6 +9,6 @@ internal static partial class Interop internal static partial class Sys { [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_SearchPath_TempDirectory")] - internal static extern string? SearchPathTempDirectory(); + internal static extern string SearchPathTempDirectory(); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.NoniOS.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.NoniOS.cs index 85aed33038283..8fbc337d59fc7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.NoniOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.NoniOS.cs @@ -5,6 +5,6 @@ namespace System.IO { public static partial class Path { - private static string? DefaultTempPath => "/tmp/"; + private static string DefaultTempPath = "/tmp/"; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.cs index 45e587f6d371f..f3ec19941c21b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.cs @@ -86,7 +86,7 @@ public static string GetTempPath() // If it is, return it, ensuring it ends with a slash. string? path = Environment.GetEnvironmentVariable(TempEnvVar); return - string.IsNullOrEmpty(path) ? DefaultTempPath! : + string.IsNullOrEmpty(path) ? DefaultTempPath : PathInternal.IsDirectorySeparator(path[path.Length - 1]) ? path : path + PathInternal.DirectorySeparatorChar; } diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs index a52b0070aede4..89c13905c4aa9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs @@ -7,13 +7,15 @@ namespace System.IO { public static partial class Path { - private static string? s_defaultTempPath; + private static string s_defaultTempPath = string.Empty; - private static string? DefaultTempPath + private static string DefaultTempPath { get { - s_defaultTempPath ??= Interop.Sys.SearchPathTempDirectory()!; + s_defaultTempPath = Interop.Sys.SearchPathTempDirectory(); + if (s_defaultTempPath == null) + throw new ExternalException(); return s_defaultTempPath!; } } From fc2cf38d49582b85a6e918186249599a8aca51e7 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 23 Aug 2021 09:42:28 -0400 Subject: [PATCH 20/30] Revert AppDominTests changes, not clear they're needed --- .../tests/System/AppDomainTests.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Runtime.Extensions/tests/System/AppDomainTests.cs b/src/libraries/System.Runtime.Extensions/tests/System/AppDomainTests.cs index 1ea1ed76ab581..e9fe758b834f7 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/AppDomainTests.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/AppDomainTests.cs @@ -763,16 +763,14 @@ public void SetThreadPrincipal() private void CopyTestAssemblies() { - string curDirectory = PlatformDetection.IsNotAppleMobile ? Environment.CurrentDirectory : Environment.GetFolderPath(Environment.SpecialFolder.InternetCache); - - string destTestAssemblyPath = Path.Combine(curDirectory, "AssemblyResolveTestApp", "AssemblyResolveTestApp.dll"); + string destTestAssemblyPath = Path.Combine(Environment.CurrentDirectory, "AssemblyResolveTestApp", "AssemblyResolveTestApp.dll"); if (!File.Exists(destTestAssemblyPath) && File.Exists("AssemblyResolveTestApp.dll")) { Directory.CreateDirectory(Path.GetDirectoryName(destTestAssemblyPath)); File.Copy("AssemblyResolveTestApp.dll", destTestAssemblyPath, false); } - destTestAssemblyPath = Path.Combine(curDirectory, "TestAppOutsideOfTPA", "TestAppOutsideOfTPA.exe"); + destTestAssemblyPath = Path.Combine(Environment.CurrentDirectory, "TestAppOutsideOfTPA", "TestAppOutsideOfTPA.exe"); if (!File.Exists(destTestAssemblyPath) && File.Exists("TestAppOutsideOfTPA.exe")) { Directory.CreateDirectory(Path.GetDirectoryName(destTestAssemblyPath)); From 74ddcff8e05db9739c5b64d9a09123b685b26b53 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 23 Aug 2021 12:41:52 -0400 Subject: [PATCH 21/30] namespace --- .../System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs index 89c13905c4aa9..13d04aab93674 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs @@ -15,7 +15,7 @@ private static string DefaultTempPath { s_defaultTempPath = Interop.Sys.SearchPathTempDirectory(); if (s_defaultTempPath == null) - throw new ExternalException(); + throw new System.Runtime.InteropServices.ExternalException(); return s_defaultTempPath!; } } From a619fa7f3b444ad61a637738027a0ba2bc043c89 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 23 Aug 2021 13:36:59 -0400 Subject: [PATCH 22/30] Update src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com> --- .../src/System/IO/Path.Unix.iOS.cs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs index 13d04aab93674..416311e6b7fe8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs @@ -9,15 +9,8 @@ public static partial class Path { private static string s_defaultTempPath = string.Empty; - private static string DefaultTempPath - { - get - { - s_defaultTempPath = Interop.Sys.SearchPathTempDirectory(); - if (s_defaultTempPath == null) - throw new System.Runtime.InteropServices.ExternalException(); - return s_defaultTempPath!; - } - } + private static string DefaultTempPath => + s_defaultTempPath ?? (s_defaultTempPath = Interop.Sys.SearchPathTempDirectory()) ?? + throw new System.Runtime.InteropServices.ExternalException(); } } From 33788e10383e9159ce6401061ee7712474ff9de0 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 23 Aug 2021 13:37:23 -0400 Subject: [PATCH 23/30] Revert unused props --- .../Common/tests/TestUtilities/System/PlatformDetection.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index 6425916da32aa..efef067dbce64 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -40,8 +40,6 @@ public static partial class PlatformDetection public static bool IsNotBrowser => !IsBrowser; public static bool IsMobile => IsBrowser || IsMacCatalyst || IsiOS || IstvOS || IsAndroid; public static bool IsNotMobile => !IsMobile; - public static bool IsAppleMobile => IsMacCatalyst || IsiOS || IstvOS; - public static bool IsNotAppleMobile => !IsAppleMobile; public static bool IsNotNetFramework => !IsNetFramework; public static bool IsArmProcess => RuntimeInformation.ProcessArchitecture == Architecture.Arm; From a3d96ed0bfaa34a115ffbfcd43efd6a0b188e20e Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 23 Aug 2021 14:22:45 -0400 Subject: [PATCH 24/30] Update src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Alexander Köplinger --- .../System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs index 416311e6b7fe8..93b5e38b81d63 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs @@ -11,6 +11,6 @@ public static partial class Path private static string DefaultTempPath => s_defaultTempPath ?? (s_defaultTempPath = Interop.Sys.SearchPathTempDirectory()) ?? - throw new System.Runtime.InteropServices.ExternalException(); + ThrowHelper.ThrowInvalidOperationException(); } } From 0baf69f3dbf3418ebe41e64de66c9db4acf46dc2 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 23 Aug 2021 14:22:58 -0400 Subject: [PATCH 25/30] Update src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com> --- .../System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs index 93b5e38b81d63..2637ed284ca01 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs @@ -7,7 +7,7 @@ namespace System.IO { public static partial class Path { - private static string s_defaultTempPath = string.Empty; + private static string? s_defaultTempPath = null; private static string DefaultTempPath => s_defaultTempPath ?? (s_defaultTempPath = Interop.Sys.SearchPathTempDirectory()) ?? From e85a9e43f8a95ddcb02b50dcd21564fe5020df91 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 23 Aug 2021 15:05:24 -0400 Subject: [PATCH 26/30] Update src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com> --- .../System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs index 2637ed284ca01..e7cf1cc3efae5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs @@ -9,8 +9,8 @@ public static partial class Path { private static string? s_defaultTempPath = null; - private static string DefaultTempPath => - s_defaultTempPath ?? (s_defaultTempPath = Interop.Sys.SearchPathTempDirectory()) ?? - ThrowHelper.ThrowInvalidOperationException(); + private static string DefaultTempPath => + s_defaultTempPath ?? (s_defaultTempPath = Interop.Sys.SearchPathTempDirectory()) ?? + ThrowHelper.ThrowInvalidOperationException(); } } From 6f338fa5725a1defcf9486d65b4613a636ef3b70 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 23 Aug 2021 15:07:49 -0400 Subject: [PATCH 27/30] Update src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.NoniOS.cs Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com> --- .../System.Private.CoreLib/src/System/IO/Path.Unix.NoniOS.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.NoniOS.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.NoniOS.cs index 8fbc337d59fc7..b2a9a4b06a083 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.NoniOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.NoniOS.cs @@ -5,6 +5,6 @@ namespace System.IO { public static partial class Path { - private static string DefaultTempPath = "/tmp/"; + private static string DefaultTempPath => "/tmp/"; } } From eb5706a46b54f00c62ecd51fc3b473aa7a9a40fc Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 23 Aug 2021 16:08:18 -0400 Subject: [PATCH 28/30] Changes squashing other changes, bleh --- .../System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs index e7cf1cc3efae5..aab5f211bb9ab 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs @@ -7,7 +7,7 @@ namespace System.IO { public static partial class Path { - private static string? s_defaultTempPath = null; + private static string s_defaultTempPath = string.Empty; private static string DefaultTempPath => s_defaultTempPath ?? (s_defaultTempPath = Interop.Sys.SearchPathTempDirectory()) ?? From 67a6c1d1aa2b1aa273a57b89c8694064b38488ea Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 23 Aug 2021 16:37:17 -0400 Subject: [PATCH 29/30] Update src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs Co-authored-by: Adeel Mujahid <3840695+am11@users.noreply.github.com> --- .../System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs index aab5f211bb9ab..136f419cf329b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs @@ -7,10 +7,10 @@ namespace System.IO { public static partial class Path { - private static string s_defaultTempPath = string.Empty; + private static string? s_defaultTempPath = null; private static string DefaultTempPath => s_defaultTempPath ?? (s_defaultTempPath = Interop.Sys.SearchPathTempDirectory()) ?? - ThrowHelper.ThrowInvalidOperationException(); + throw new InvalidOperationException(); } } From e3cbd8c686a6890608e95a508fad76c9ddad3386 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 23 Aug 2021 16:40:12 -0400 Subject: [PATCH 30/30] error CA1805: Member 's_defaultTempPath' is explicitly initialized to its default value --- .../System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs index 136f419cf329b..c1c4a7047eec5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.iOS.cs @@ -7,7 +7,7 @@ namespace System.IO { public static partial class Path { - private static string? s_defaultTempPath = null; + private static string? s_defaultTempPath; private static string DefaultTempPath => s_defaultTempPath ?? (s_defaultTempPath = Interop.Sys.SearchPathTempDirectory()) ??