blob: c501aa89fb62494f4174766e1d3937cda37f8b68 [file] [log] [blame]
Jan Tattermuschafab5412016-01-12 17:57:25 -08001#region Copyright notice and license
2
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003// Copyright 2015 gRPC authors.
Jan Tattermuschafab5412016-01-12 17:57:25 -08004//
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
Jan Tattermuschafab5412016-01-12 17:57:25 -08008//
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009// http://www.apache.org/licenses/LICENSE-2.0
Jan Tattermuschafab5412016-01-12 17:57:25 -080010//
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
Jan Tattermuschafab5412016-01-12 17:57:25 -080016
17#endregion
18
19using System;
20using System.Collections.Concurrent;
21using System.Diagnostics;
22using System.IO;
23using System.Reflection;
24using System.Runtime.InteropServices;
25using System.Threading;
Jan Tattermuschd35471a2018-03-07 20:37:02 +010026using Grpc.Core.Utils;
Jan Tattermuschafab5412016-01-12 17:57:25 -080027
28namespace Grpc.Core.Internal
29{
30 /// <summary>
31 /// Utility methods for detecting platform and architecture.
32 /// </summary>
33 internal static class PlatformApis
34 {
Jan Tattermusch660547d2018-03-07 21:49:23 +010035 const string UnityEngineApplicationClassName = "UnityEngine.Application, UnityEngine";
Jan Tattermusch0b907fc2018-07-23 19:13:41 +020036 const string XamarinAndroidObjectClassName = "Java.Lang.Object, Mono.Android";
37 const string XamarinIOSObjectClassName = "Foundation.NSObject, Xamarin.iOS";
38
Jan Tattermuschafab5412016-01-12 17:57:25 -080039 static readonly bool isLinux;
40 static readonly bool isMacOSX;
41 static readonly bool isWindows;
Jan Tattermuschdd133c12016-01-31 17:07:58 -080042 static readonly bool isMono;
Jan Tattermusch4d2df962016-09-21 19:57:10 +020043 static readonly bool isNetCore;
Jan Tattermuscha1b0ee22018-03-06 09:20:38 +010044 static readonly bool isUnity;
Alexander Houben7a7e09c2018-06-30 20:45:33 +020045 static readonly bool isXamarin;
Jan Tattermusch0b907fc2018-07-23 19:13:41 +020046 static readonly bool isXamarinIOS;
Alexander Houben7a7e09c2018-06-30 20:45:33 +020047 static readonly bool isXamarinAndroid;
Jan Tattermuschafab5412016-01-12 17:57:25 -080048
49 static PlatformApis()
50 {
Jan Tattermusch317b8ac2016-06-16 09:36:11 -070051#if NETSTANDARD1_5
Chris Baconc65ceef2016-02-05 09:04:46 +000052 isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
53 isMacOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
54 isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
Jan Tattermusch4d2df962016-09-21 19:57:10 +020055 isNetCore = RuntimeInformation.FrameworkDescription.StartsWith(".NET Core");
Chris Baconc65ceef2016-02-05 09:04:46 +000056#else
Jan Tattermuschafab5412016-01-12 17:57:25 -080057 var platform = Environment.OSVersion.Platform;
58
59 // PlatformID.MacOSX is never returned, commonly used trick is to identify Mac is by using uname.
60 isMacOSX = (platform == PlatformID.Unix && GetUname() == "Darwin");
61 isLinux = (platform == PlatformID.Unix && !isMacOSX);
62 isWindows = (platform == PlatformID.Win32NT || platform == PlatformID.Win32S || platform == PlatformID.Win32Windows);
Jan Tattermusch4d2df962016-09-21 19:57:10 +020063 isNetCore = false;
Chris Baconc65ceef2016-02-05 09:04:46 +000064#endif
Jan Tattermuschdd133c12016-01-31 17:07:58 -080065 isMono = Type.GetType("Mono.Runtime") != null;
Jan Tattermusch660547d2018-03-07 21:49:23 +010066 isUnity = Type.GetType(UnityEngineApplicationClassName) != null;
Jan Tattermusch0b907fc2018-07-23 19:13:41 +020067 isXamarinIOS = Type.GetType(XamarinIOSObjectClassName) != null;
68 isXamarinAndroid = Type.GetType(XamarinAndroidObjectClassName) != null;
69 isXamarin = isXamarinIOS || isXamarinAndroid;
Jan Tattermuschafab5412016-01-12 17:57:25 -080070 }
71
72 public static bool IsLinux
73 {
74 get { return isLinux; }
75 }
76
77 public static bool IsMacOSX
78 {
79 get { return isMacOSX; }
80 }
81
82 public static bool IsWindows
83 {
84 get { return isWindows; }
85 }
86
Jan Tattermuschdd133c12016-01-31 17:07:58 -080087 public static bool IsMono
88 {
89 get { return isMono; }
90 }
91
Jan Tattermusch4d2df962016-09-21 19:57:10 +020092 /// <summary>
Jan Tattermuscha1b0ee22018-03-06 09:20:38 +010093 /// true if running on Unity platform.
94 /// </summary>
95 public static bool IsUnity
96 {
97 get { return isUnity; }
98 }
99
100 /// <summary>
Alexander Houben7a7e09c2018-06-30 20:45:33 +0200101 /// true if running on a Xamarin platform (either Xamarin.Android or Xamarin.iOS),
102 /// false otherwise.
103 /// </summary>
104 public static bool IsXamarin
105 {
106 get { return isXamarin; }
107 }
108
109 /// <summary>
110 /// true if running on Xamarin.iOS, false otherwise.
111 /// </summary>
Jan Tattermusch0b907fc2018-07-23 19:13:41 +0200112 public static bool IsXamarinIOS
Alexander Houben7a7e09c2018-06-30 20:45:33 +0200113 {
Jan Tattermusch0b907fc2018-07-23 19:13:41 +0200114 get { return isXamarinIOS; }
Alexander Houben7a7e09c2018-06-30 20:45:33 +0200115 }
116
117 /// <summary>
118 /// true if running on Xamarin.Android, false otherwise.
119 /// </summary>
120 public static bool IsXamarinAndroid
121 {
122 get { return isXamarinAndroid; }
123 }
124
125 /// <summary>
Jan Tattermusch4d2df962016-09-21 19:57:10 +0200126 /// true if running on .NET Core (CoreCLR), false otherwise.
127 /// </summary>
128 public static bool IsNetCore
129 {
130 get { return isNetCore; }
131 }
132
Jan Tattermuschafab5412016-01-12 17:57:25 -0800133 public static bool Is64Bit
134 {
135 get { return IntPtr.Size == 8; }
136 }
137
Jan Tattermuschd35471a2018-03-07 20:37:02 +0100138 /// <summary>
139 /// Returns <c>UnityEngine.Application.platform</c> as a string.
140 /// See https://docs.unity3d.com/ScriptReference/Application-platform.html for possible values.
141 /// Value is obtained via reflection to avoid compile-time dependency on Unity.
142 /// This method should only be called if <c>IsUnity</c> is <c>true</c>.
143 /// </summary>
144 public static string GetUnityRuntimePlatform()
145 {
146 GrpcPreconditions.CheckState(IsUnity, "Not running on Unity.");
Jan Tattermusch660547d2018-03-07 21:49:23 +0100147#if NETSTANDARD1_5
148 return Type.GetType(UnityEngineApplicationClassName).GetTypeInfo().GetProperty("platform").GetValue(null).ToString();
149#else
150 return Type.GetType(UnityEngineApplicationClassName).GetProperty("platform").GetValue(null).ToString();
151#endif
Jan Tattermuschd35471a2018-03-07 20:37:02 +0100152 }
153
Jan Tattermuschafab5412016-01-12 17:57:25 -0800154 [DllImport("libc")]
155 static extern int uname(IntPtr buf);
156
157 static string GetUname()
158 {
159 var buffer = Marshal.AllocHGlobal(8192);
160 try
161 {
162 if (uname(buffer) == 0)
163 {
164 return Marshal.PtrToStringAnsi(buffer);
165 }
166 return string.Empty;
167 }
168 catch
169 {
170 return string.Empty;
171 }
172 finally
173 {
174 if (buffer != IntPtr.Zero)
175 {
176 Marshal.FreeHGlobal(buffer);
177 }
178 }
179 }
180 }
181}