DeviceSettings.mm 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. #include <sys/types.h>
  2. #include <sys/sysctl.h>
  3. #include "DisplayManager.h"
  4. // ad/vendor ids
  5. #if UNITY_USES_IAD
  6. #include <AdSupport/ASIdentifierManager.h>
  7. static id QueryASIdentifierManager()
  8. {
  9. NSBundle* bundle = [NSBundle bundleWithPath: @"/System/Library/Frameworks/AdSupport.framework"];
  10. if (bundle)
  11. {
  12. [bundle load];
  13. Class retClass = [bundle classNamed: @"ASIdentifierManager"];
  14. return [retClass performSelector: @selector(sharedManager)];
  15. }
  16. return nil;
  17. }
  18. #endif
  19. extern "C" const char* UnityAdvertisingIdentifier()
  20. {
  21. static const char* _ADID = NULL;
  22. #if UNITY_USES_IAD
  23. static const NSString* _ADIDNSString = nil;
  24. // ad id can be reset during app lifetime
  25. id manager = QueryASIdentifierManager();
  26. if (manager)
  27. {
  28. NSString* adid = [[manager performSelector: @selector(advertisingIdentifier)] UUIDString];
  29. // Do stuff to avoid UTF8String leaks. We still leak if ADID changes, but that shouldn't happen too often.
  30. if (![_ADIDNSString isEqualToString: adid])
  31. {
  32. _ADIDNSString = adid;
  33. free((void*)_ADID);
  34. _ADID = AllocCString(adid);
  35. }
  36. }
  37. #endif
  38. return _ADID;
  39. }
  40. extern "C" int UnityAdvertisingTrackingEnabled()
  41. {
  42. bool _AdTrackingEnabled = false;
  43. #if UNITY_USES_IAD
  44. // ad tracking can be changed during app lifetime
  45. id manager = QueryASIdentifierManager();
  46. if (manager)
  47. _AdTrackingEnabled = [manager performSelector: @selector(isAdvertisingTrackingEnabled)];
  48. #endif
  49. return _AdTrackingEnabled ? 1 : 0;
  50. }
  51. extern "C" const char* UnityVendorIdentifier()
  52. {
  53. static const char* _VendorID = NULL;
  54. if (_VendorID == NULL)
  55. _VendorID = AllocCString([[UIDevice currentDevice].identifierForVendor UUIDString]);
  56. return _VendorID;
  57. }
  58. // UIDevice properties
  59. #define QUERY_UIDEVICE_PROPERTY(FUNC, PROP) \
  60. extern "C" const char* FUNC() \
  61. { \
  62. static const char* value = NULL; \
  63. if (value == NULL && [UIDevice instancesRespondToSelector:@selector(PROP)]) \
  64. value = AllocCString([UIDevice currentDevice].PROP); \
  65. return value; \
  66. }
  67. QUERY_UIDEVICE_PROPERTY(UnityDeviceName, name)
  68. QUERY_UIDEVICE_PROPERTY(UnitySystemName, systemName)
  69. QUERY_UIDEVICE_PROPERTY(UnitySystemVersion, systemVersion)
  70. #undef QUERY_UIDEVICE_PROPERTY
  71. // hw info
  72. extern "C" const char* UnityDeviceModel()
  73. {
  74. static const char* _DeviceModel = NULL;
  75. if (_DeviceModel == NULL)
  76. {
  77. size_t size;
  78. ::sysctlbyname("hw.machine", NULL, &size, NULL, 0);
  79. char* model = (char*)::malloc(size + 1);
  80. ::sysctlbyname("hw.machine", model, &size, NULL, 0);
  81. model[size] = 0;
  82. _DeviceModel = AllocCString([NSString stringWithUTF8String: model]);
  83. ::free(model);
  84. }
  85. return _DeviceModel;
  86. }
  87. extern "C" int UnityDeviceCPUCount()
  88. {
  89. static int _DeviceCPUCount = -1;
  90. if (_DeviceCPUCount <= 0)
  91. {
  92. // maybe would be better to use HW_AVAILCPU
  93. int ctlName[] = {CTL_HW, HW_NCPU};
  94. size_t dataLen = sizeof(_DeviceCPUCount);
  95. ::sysctl(ctlName, 2, &_DeviceCPUCount, &dataLen, NULL, 0);
  96. }
  97. return _DeviceCPUCount;
  98. }
  99. extern "C" int UnityGetPhysicalMemory()
  100. {
  101. return ([[NSProcessInfo processInfo] physicalMemory]) / (1024 * 1024);
  102. }
  103. // misc
  104. extern "C" const char* UnitySystemLanguage()
  105. {
  106. static const char* _SystemLanguage = NULL;
  107. if (_SystemLanguage == NULL)
  108. {
  109. NSArray* lang = [[NSUserDefaults standardUserDefaults] objectForKey: @"AppleLanguages"];
  110. if (lang.count > 0)
  111. _SystemLanguage = AllocCString(lang[0]);
  112. }
  113. return _SystemLanguage;
  114. }
  115. extern "C" int UnityDeviceGeneration()
  116. {
  117. static int _DeviceGeneration = deviceUnknown;
  118. if (_DeviceGeneration == deviceUnknown)
  119. {
  120. const char* model = UnityDeviceModel();
  121. if (!strcmp(model, "iPhone2,1"))
  122. _DeviceGeneration = deviceiPhone3GS;
  123. else if (!strncmp(model, "iPhone3,", 8))
  124. _DeviceGeneration = deviceiPhone4;
  125. else if (!strncmp(model, "iPhone4,", 8))
  126. _DeviceGeneration = deviceiPhone4S;
  127. else if (!strncmp(model, "iPhone5,", 8))
  128. {
  129. int rev = atoi(model + 8);
  130. if (rev >= 3)
  131. _DeviceGeneration = deviceiPhone5C; // iPhone5,3
  132. else
  133. _DeviceGeneration = deviceiPhone5;
  134. }
  135. else if (!strncmp(model, "iPhone6,", 8))
  136. _DeviceGeneration = deviceiPhone5S;
  137. else if (!strncmp(model, "iPhone7,2", 9))
  138. _DeviceGeneration = deviceiPhone6;
  139. else if (!strncmp(model, "iPhone7,1", 9))
  140. _DeviceGeneration = deviceiPhone6Plus;
  141. else if (!strncmp(model, "iPhone8,1", 9))
  142. _DeviceGeneration = deviceiPhone6S;
  143. else if (!strncmp(model, "iPhone8,2", 9))
  144. _DeviceGeneration = deviceiPhone6SPlus;
  145. else if (!strncmp(model, "iPhone8,4", 9))
  146. _DeviceGeneration = deviceiPhoneSE1Gen;
  147. else if (!strncmp(model, "iPhone9,1", 9) || !strncmp(model, "iPhone9,3", 9))
  148. _DeviceGeneration = deviceiPhone7;
  149. else if (!strncmp(model, "iPhone9,2", 9) || !strncmp(model, "iPhone9,4", 9))
  150. _DeviceGeneration = deviceiPhone7Plus;
  151. else if (!strncmp(model, "iPhone10,1", 10) || !strncmp(model, "iPhone10,4", 10))
  152. _DeviceGeneration = deviceiPhone8;
  153. else if (!strncmp(model, "iPhone10,2", 10) || !strncmp(model, "iPhone10,5", 10))
  154. _DeviceGeneration = deviceiPhone8Plus;
  155. else if (!strncmp(model, "iPhone10,3", 10) || !strncmp(model, "iPhone10,6", 10))
  156. _DeviceGeneration = deviceiPhoneX;
  157. else if (!strncmp(model, "iPhone11,8", 10))
  158. _DeviceGeneration = deviceiPhoneXR;
  159. else if (!strncmp(model, "iPhone11,2", 10))
  160. _DeviceGeneration = deviceiPhoneXS;
  161. else if (!strncmp(model, "iPhone11,4", 10) || !strncmp(model, "iPhone11,6", 10))
  162. _DeviceGeneration = deviceiPhoneXSMax;
  163. else if (!strncmp(model, "iPhone12,1", 11))
  164. _DeviceGeneration = deviceiPhone11;
  165. else if (!strncmp(model, "iPhone12,3", 11))
  166. _DeviceGeneration = deviceiPhone11Pro;
  167. else if (!strncmp(model, "iPhone12,5", 11))
  168. _DeviceGeneration = deviceiPhone11ProMax;
  169. else if (!strcmp(model, "iPod4,1"))
  170. _DeviceGeneration = deviceiPodTouch4Gen;
  171. else if (!strncmp(model, "iPod5,", 6))
  172. _DeviceGeneration = deviceiPodTouch5Gen;
  173. else if (!strncmp(model, "iPod7,", 6))
  174. _DeviceGeneration = deviceiPodTouch6Gen;
  175. else if (!strncmp(model, "iPad2,", 6))
  176. {
  177. int rev = atoi(model + 6);
  178. if (rev >= 5)
  179. _DeviceGeneration = deviceiPadMini1Gen; // iPad2,5
  180. else
  181. _DeviceGeneration = deviceiPad2Gen;
  182. }
  183. else if (!strncmp(model, "iPad3,", 6))
  184. {
  185. int rev = atoi(model + 6);
  186. if (rev >= 4)
  187. _DeviceGeneration = deviceiPad4Gen; // iPad3,4
  188. else
  189. _DeviceGeneration = deviceiPad3Gen;
  190. }
  191. else if (!strncmp(model, "iPad4,", 6))
  192. {
  193. int rev = atoi(model + 6);
  194. if (rev >= 7)
  195. _DeviceGeneration = deviceiPadMini3Gen;
  196. else if (rev >= 4)
  197. _DeviceGeneration = deviceiPadMini2Gen; // iPad4,4
  198. else
  199. _DeviceGeneration = deviceiPadAir1;
  200. }
  201. else if (!strncmp(model, "iPad5,", 6))
  202. {
  203. int rev = atoi(model + 6);
  204. if (rev == 1 || rev == 2)
  205. _DeviceGeneration = deviceiPadMini4Gen;
  206. else if (rev >= 3)
  207. _DeviceGeneration = deviceiPadAir2;
  208. }
  209. else if (!strncmp(model, "iPad6,", 6))
  210. {
  211. int rev = atoi(model + 6);
  212. if (rev == 7 || rev == 8)
  213. _DeviceGeneration = deviceiPadPro1Gen;
  214. else if (rev == 3 || rev == 4)
  215. _DeviceGeneration = deviceiPadPro10Inch1Gen;
  216. else if (rev == 11 || rev == 12)
  217. _DeviceGeneration = deviceiPad5Gen;
  218. }
  219. else if (!strncmp(model, "iPad7,", 6))
  220. {
  221. int rev = atoi(model + 6);
  222. if (rev == 1 || rev == 2)
  223. _DeviceGeneration = deviceiPadPro2Gen;
  224. else if (rev == 3 || rev == 4)
  225. _DeviceGeneration = deviceiPadPro10Inch2Gen;
  226. }
  227. else if (!strncmp(model, "iPad8,", 6))
  228. {
  229. int rev = atoi(model + 6);
  230. if (rev >= 1 && rev <= 4)
  231. _DeviceGeneration = deviceiPadPro11Inch;
  232. else if (rev >= 5)
  233. _DeviceGeneration = deviceiPadPro3Gen;
  234. }
  235. // completely unknown hw - just determine form-factor
  236. if (_DeviceGeneration == deviceUnknown)
  237. {
  238. if (!strncmp(model, "iPhone", 6))
  239. _DeviceGeneration = deviceiPhoneUnknown;
  240. else if (!strncmp(model, "iPad", 4))
  241. _DeviceGeneration = deviceiPadUnknown;
  242. else if (!strncmp(model, "iPod", 4))
  243. _DeviceGeneration = deviceiPodTouchUnknown;
  244. else
  245. _DeviceGeneration = deviceUnknown;
  246. }
  247. }
  248. return _DeviceGeneration;
  249. }
  250. extern "C" int UnityDeviceSupportsUpsideDown()
  251. {
  252. switch (UnityDeviceGeneration())
  253. {
  254. // devices without home button
  255. case deviceiPhoneX: case deviceiPhoneXS: case deviceiPhoneXSMax: case deviceiPhoneXR:
  256. case deviceiPhone11: case deviceiPhone11Pro: case deviceiPhone11ProMax:
  257. return 0;
  258. default:
  259. return 1;
  260. }
  261. }
  262. extern "C" int UnityDeviceIsStylusTouchSupported()
  263. {
  264. int deviceGen = UnityDeviceGeneration();
  265. return (deviceGen == deviceiPadPro1Gen ||
  266. deviceGen == deviceiPadPro10Inch1Gen ||
  267. deviceGen == deviceiPadPro2Gen ||
  268. deviceGen == deviceiPadPro10Inch2Gen) ? 1 : 0;
  269. }
  270. extern "C" int UnityDeviceIsWideColorSupported()
  271. {
  272. UIScreen* mainScreen = [UIScreen mainScreen];
  273. if (![mainScreen respondsToSelector: @selector(traitCollection)])
  274. return false;
  275. UITraitCollection* traits = mainScreen.traitCollection;
  276. if (![traits respondsToSelector: @selector(displayGamut)])
  277. return false;
  278. #if UNITY_HAS_IOSSDK_10_0 || UNITY_HAS_TVOSSDK_10_0
  279. return traits.displayGamut == UIDisplayGamutP3;
  280. #else
  281. return false;
  282. #endif
  283. }
  284. extern "C" float UnityDeviceDPI()
  285. {
  286. static float _DeviceDPI = -1.0f;
  287. if (_DeviceDPI < 0.0f)
  288. {
  289. switch (UnityDeviceGeneration())
  290. {
  291. // iPhone
  292. case deviceiPhone3GS:
  293. _DeviceDPI = 163.0f; break;
  294. case deviceiPhone4:
  295. case deviceiPhone4S:
  296. case deviceiPhone5:
  297. case deviceiPhone5C:
  298. case deviceiPhone5S:
  299. case deviceiPhone6:
  300. case deviceiPhone6S:
  301. case deviceiPhoneSE1Gen:
  302. case deviceiPhone7:
  303. case deviceiPhone8:
  304. case deviceiPhoneXR:
  305. case deviceiPhone11:
  306. _DeviceDPI = 326.0f; break;
  307. case deviceiPhone6Plus:
  308. case deviceiPhone6SPlus:
  309. case deviceiPhone7Plus:
  310. case deviceiPhone8Plus:
  311. _DeviceDPI = 401.0f; break;
  312. case deviceiPhoneX:
  313. case deviceiPhoneXS:
  314. case deviceiPhoneXSMax:
  315. case deviceiPhone11Pro:
  316. case deviceiPhone11ProMax:
  317. _DeviceDPI = 458.0f; break;
  318. // iPad
  319. case deviceiPad2Gen:
  320. _DeviceDPI = 132.0f; break;
  321. case deviceiPad3Gen:
  322. case deviceiPad4Gen: // iPad retina
  323. case deviceiPadAir1:
  324. case deviceiPadAir2:
  325. case deviceiPadPro1Gen:
  326. case deviceiPadPro10Inch1Gen:
  327. case deviceiPadPro2Gen:
  328. case deviceiPadPro10Inch2Gen:
  329. case deviceiPad5Gen:
  330. case deviceiPadPro11Inch:
  331. case deviceiPadPro3Gen:
  332. _DeviceDPI = 264.0f; break;
  333. // iPad mini
  334. case deviceiPadMini1Gen:
  335. _DeviceDPI = 163.0f; break;
  336. case deviceiPadMini2Gen:
  337. case deviceiPadMini3Gen:
  338. case deviceiPadMini4Gen:
  339. _DeviceDPI = 326.0f; break;
  340. // iPod
  341. case deviceiPodTouch4Gen:
  342. case deviceiPodTouch5Gen:
  343. case deviceiPodTouch6Gen:
  344. _DeviceDPI = 326.0f; break;
  345. // unknown (new) devices
  346. case deviceiPhoneUnknown:
  347. _DeviceDPI = 326.0f; break;
  348. case deviceiPadUnknown:
  349. _DeviceDPI = 264.0f; break;
  350. case deviceiPodTouchUnknown:
  351. _DeviceDPI = 326.0f; break;
  352. }
  353. // If we didn't find DPI, set it to "unknown" value.
  354. if (_DeviceDPI < 0.0f)
  355. _DeviceDPI = 0.0f;
  356. }
  357. return _DeviceDPI;
  358. }
  359. // device id with fallback for pre-ios7
  360. extern "C" const char* UnityDeviceUniqueIdentifier()
  361. {
  362. static const char* _DeviceID = NULL;
  363. if (_DeviceID == NULL)
  364. _DeviceID = UnityVendorIdentifier();
  365. return _DeviceID;
  366. }