DeviceSettings.mm 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  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 UnityGetLowPowerModeEnabled()
  41. {
  42. return [[NSProcessInfo processInfo] isLowPowerModeEnabled] ? 1 : 0;
  43. }
  44. extern "C" int UnityGetWantsSoftwareDimming()
  45. {
  46. #if !PLATFORM_TVOS
  47. UIScreen* mainScreen = [UIScreen mainScreen];
  48. return mainScreen.wantsSoftwareDimming ? 1 : 0;
  49. #else
  50. return 0;
  51. #endif
  52. }
  53. extern "C" void UnitySetWantsSoftwareDimming(int enabled)
  54. {
  55. #if !PLATFORM_TVOS
  56. UIScreen* mainScreen = [UIScreen mainScreen];
  57. mainScreen.wantsSoftwareDimming = enabled;
  58. #endif
  59. }
  60. extern "C" int UnityAdvertisingTrackingEnabled()
  61. {
  62. bool _AdTrackingEnabled = false;
  63. #if UNITY_USES_IAD
  64. // ad tracking can be changed during app lifetime
  65. id manager = QueryASIdentifierManager();
  66. if (manager)
  67. _AdTrackingEnabled = [manager performSelector: @selector(isAdvertisingTrackingEnabled)];
  68. #endif
  69. return _AdTrackingEnabled ? 1 : 0;
  70. }
  71. extern "C" const char* UnityVendorIdentifier()
  72. {
  73. static const char* _VendorID = NULL;
  74. if (_VendorID == NULL)
  75. _VendorID = AllocCString([[UIDevice currentDevice].identifierForVendor UUIDString]);
  76. return _VendorID;
  77. }
  78. // UIDevice properties
  79. #define QUERY_UIDEVICE_PROPERTY(FUNC, PROP) \
  80. extern "C" const char* FUNC() \
  81. { \
  82. static const char* value = NULL; \
  83. if (value == NULL && [UIDevice instancesRespondToSelector:@selector(PROP)]) \
  84. value = AllocCString([UIDevice currentDevice].PROP); \
  85. return value; \
  86. }
  87. QUERY_UIDEVICE_PROPERTY(UnityDeviceName, name)
  88. QUERY_UIDEVICE_PROPERTY(UnitySystemName, systemName)
  89. QUERY_UIDEVICE_PROPERTY(UnitySystemVersion, systemVersion)
  90. #undef QUERY_UIDEVICE_PROPERTY
  91. // hw info
  92. extern "C" const char* UnityDeviceModel()
  93. {
  94. static const char* _DeviceModel = NULL;
  95. if (_DeviceModel == NULL)
  96. {
  97. size_t size;
  98. ::sysctlbyname("hw.machine", NULL, &size, NULL, 0);
  99. char* model = (char*)::malloc(size + 1);
  100. ::sysctlbyname("hw.machine", model, &size, NULL, 0);
  101. model[size] = 0;
  102. #if TARGET_OS_SIMULATOR
  103. if (!strncmp(model, "i386", 4) || !strncmp(model, "x86_64", 6))
  104. {
  105. NSString* simModel = [[NSProcessInfo processInfo] environment][@"SIMULATOR_MODEL_IDENTIFIER"];
  106. if ([simModel length] > 0)
  107. {
  108. _DeviceModel = AllocCString(simModel);
  109. ::free(model);
  110. return _DeviceModel;
  111. }
  112. }
  113. #endif
  114. _DeviceModel = AllocCString([NSString stringWithUTF8String: model]);
  115. ::free(model);
  116. }
  117. return _DeviceModel;
  118. }
  119. extern "C" int UnityDeviceCPUCount()
  120. {
  121. static int _DeviceCPUCount = -1;
  122. if (_DeviceCPUCount <= 0)
  123. {
  124. // maybe would be better to use HW_AVAILCPU
  125. int ctlName[] = {CTL_HW, HW_NCPU};
  126. size_t dataLen = sizeof(_DeviceCPUCount);
  127. ::sysctl(ctlName, 2, &_DeviceCPUCount, &dataLen, NULL, 0);
  128. }
  129. return _DeviceCPUCount;
  130. }
  131. extern "C" int UnityGetPhysicalMemory()
  132. {
  133. return ([[NSProcessInfo processInfo] physicalMemory]) / (1024 * 1024);
  134. }
  135. // misc
  136. extern "C" const char* UnitySystemLanguage()
  137. {
  138. static const char* _SystemLanguage = NULL;
  139. if (_SystemLanguage == NULL)
  140. {
  141. NSArray* lang = [[NSUserDefaults standardUserDefaults] objectForKey: @"AppleLanguages"];
  142. if (lang.count > 0)
  143. _SystemLanguage = AllocCString(lang[0]);
  144. }
  145. return _SystemLanguage;
  146. }
  147. enum DeviceType : uint8_t
  148. {
  149. deviceTypeUnknown = 0,
  150. iPhone = 1,
  151. iPad = 2,
  152. iPod = 3,
  153. AppleTV = 4
  154. };
  155. struct DeviceTableEntry
  156. {
  157. DeviceType deviceType;
  158. uint8_t majorGen;
  159. uint8_t minorGenMin;
  160. uint8_t minorGenMax;
  161. DeviceGeneration device;
  162. };
  163. DeviceTableEntry DeviceTable[] =
  164. {
  165. { iPhone, 2, 1, 1, deviceiPhone3GS },
  166. { iPhone, 3, 1, 3, deviceiPhone4 },
  167. { iPhone, 4, 1, 1, deviceiPhone4S },
  168. { iPhone, 5, 3, 4, deviceiPhone5C },
  169. { iPhone, 5, 1, 2, deviceiPhone5 },
  170. { iPhone, 6, 1, 2, deviceiPhone5S },
  171. { iPhone, 7, 2, 2, deviceiPhone6 },
  172. { iPhone, 7, 1, 1, deviceiPhone6Plus },
  173. { iPhone, 8, 1, 1, deviceiPhone6S },
  174. { iPhone, 8, 2, 2, deviceiPhone6SPlus },
  175. { iPhone, 8, 4, 4, deviceiPhoneSE1Gen },
  176. { iPhone, 9, 1, 1, deviceiPhone7 },
  177. { iPhone, 9, 3, 3, deviceiPhone7 },
  178. { iPhone, 9, 2, 2, deviceiPhone7Plus },
  179. { iPhone, 9, 4, 4, deviceiPhone7Plus },
  180. { iPhone, 10, 1, 1, deviceiPhone8 },
  181. { iPhone, 10, 4, 4, deviceiPhone8 },
  182. { iPhone, 10, 2, 2, deviceiPhone8Plus },
  183. { iPhone, 10, 5, 5, deviceiPhone8Plus },
  184. { iPhone, 10, 3, 3, deviceiPhoneX },
  185. { iPhone, 10, 6, 6, deviceiPhoneX },
  186. { iPhone, 11, 8, 8, deviceiPhoneXR },
  187. { iPhone, 11, 2, 2, deviceiPhoneXS },
  188. { iPhone, 11, 4, 4, deviceiPhoneXSMax },
  189. { iPhone, 11, 6, 6, deviceiPhoneXSMax },
  190. { iPhone, 12, 1, 1, deviceiPhone11 },
  191. { iPhone, 12, 3, 3, deviceiPhone11Pro },
  192. { iPhone, 12, 5, 5, deviceiPhone11ProMax },
  193. { iPod, 4, 1, 1, deviceiPodTouch4Gen },
  194. { iPod, 5, 1, 1, deviceiPodTouch5Gen },
  195. { iPod, 7, 1, 1, deviceiPodTouch6Gen },
  196. { iPod, 9, 1, 1, deviceiPodTouch7Gen },
  197. { iPad, 2, 5, 7, deviceiPadMini1Gen },
  198. { iPad, 4, 4, 6, deviceiPadMini2Gen },
  199. { iPad, 4, 7, 9, deviceiPadMini3Gen },
  200. { iPad, 5, 1, 2, deviceiPadMini4Gen },
  201. { iPad, 2, 1, 4, deviceiPad2Gen },
  202. { iPad, 3, 1, 3, deviceiPad3Gen },
  203. { iPad, 3, 4, 6, deviceiPad4Gen },
  204. { iPad, 6, 11, 12, deviceiPad5Gen },
  205. { iPad, 7, 5, 6, deviceiPad6Gen },
  206. { iPad, 7, 11, 12, deviceiPad7Gen },
  207. { iPad, 4, 1, 3, deviceiPadAir1 },
  208. { iPad, 5, 3, 4, deviceiPadAir2 },
  209. { iPad, 6, 7, 8, deviceiPadPro1Gen },
  210. { iPad, 7, 1, 2, deviceiPadPro2Gen },
  211. { iPad, 6, 3, 4, deviceiPadPro10Inch1Gen },
  212. { iPad, 7, 3, 4, deviceiPadPro10Inch2Gen },
  213. { iPad, 8, 1, 4, deviceiPadPro11Inch },
  214. { iPad, 8, 5, 8, deviceiPadPro3Gen },
  215. { AppleTV, 5, 3, 3, deviceAppleTV1Gen },
  216. { AppleTV, 6, 2, 2, deviceAppleTV2Gen }
  217. };
  218. extern "C" int ParseDeviceGeneration(const char* model)
  219. {
  220. DeviceType deviceType = deviceTypeUnknown;
  221. if (!strncmp(model, "iPhone", 6))
  222. {
  223. deviceType = iPhone;
  224. model += 6;
  225. }
  226. else if (!strncmp(model, "iPad", 4))
  227. {
  228. deviceType = iPad;
  229. model += 4;
  230. }
  231. else if (!strncmp(model, "iPod", 4))
  232. {
  233. deviceType = iPod;
  234. model += 4;
  235. }
  236. else if (!strncmp(model, "AppleTV", 7))
  237. {
  238. deviceType = AppleTV;
  239. model += 7;
  240. }
  241. char* endPtr;
  242. int majorGen = (int)strtol(model, &endPtr, 10);
  243. int minorGen = (int)strtol(endPtr + 1, &endPtr, 10);
  244. if (strlen(endPtr) == 0)
  245. {
  246. for (int i = 0; i < sizeof(DeviceTable) / sizeof(DeviceTable[0]); ++i)
  247. {
  248. if (deviceType != DeviceTable[i].deviceType)
  249. continue;
  250. if (majorGen != DeviceTable[i].majorGen)
  251. continue;
  252. if (minorGen < DeviceTable[i].minorGenMin || minorGen > DeviceTable[i].minorGenMax)
  253. continue;
  254. return DeviceTable[i].device;
  255. }
  256. }
  257. if (deviceType == iPhone)
  258. return deviceiPhoneUnknown;
  259. else if (deviceType == iPad)
  260. return deviceiPadUnknown;
  261. else if (deviceType == iPod)
  262. return deviceiPodTouchUnknown;
  263. return deviceUnknown;
  264. }
  265. extern "C" int UnityDeviceGeneration()
  266. {
  267. static int _DeviceGeneration = deviceUnknown;
  268. if (_DeviceGeneration == deviceUnknown)
  269. {
  270. const char* model = UnityDeviceModel();
  271. _DeviceGeneration = ParseDeviceGeneration(model);
  272. }
  273. return _DeviceGeneration;
  274. }
  275. extern "C" int UnityDeviceSupportsUpsideDown()
  276. {
  277. switch (UnityDeviceGeneration())
  278. {
  279. // devices without home button
  280. case deviceiPhoneX: case deviceiPhoneXS: case deviceiPhoneXSMax: case deviceiPhoneXR:
  281. case deviceiPhone11: case deviceiPhone11Pro: case deviceiPhone11ProMax:
  282. return 0;
  283. default:
  284. return 1;
  285. }
  286. }
  287. extern "C" int UnityDeviceSupportedOrientations()
  288. {
  289. int device = UnityDeviceGeneration();
  290. int orientations = 0;
  291. orientations |= (1 << portrait);
  292. orientations |= (1 << landscapeLeft);
  293. orientations |= (1 << landscapeRight);
  294. if (UnityDeviceSupportsUpsideDown())
  295. orientations |= (1 << portraitUpsideDown);
  296. return orientations;
  297. }
  298. extern "C" int UnityDeviceIsStylusTouchSupported()
  299. {
  300. int deviceGen = UnityDeviceGeneration();
  301. return (deviceGen == deviceiPadPro1Gen ||
  302. deviceGen == deviceiPadPro10Inch1Gen ||
  303. deviceGen == deviceiPadPro2Gen ||
  304. deviceGen == deviceiPadPro10Inch2Gen ||
  305. deviceGen == deviceiPadPro11Inch ||
  306. deviceGen == deviceiPadPro3Gen ||
  307. deviceGen == deviceiPad6Gen) ? 1 : 0;
  308. }
  309. extern "C" int UnityDeviceCanShowWideColor()
  310. {
  311. return [UIScreen mainScreen].traitCollection.displayGamut == UIDisplayGamutP3;
  312. }
  313. extern "C" float UnityDeviceDPI()
  314. {
  315. static float _DeviceDPI = -1.0f;
  316. if (_DeviceDPI < 0.0f)
  317. {
  318. switch (UnityDeviceGeneration())
  319. {
  320. // iPhone
  321. case deviceiPhone3GS:
  322. _DeviceDPI = 163.0f; break;
  323. case deviceiPhone4:
  324. case deviceiPhone4S:
  325. case deviceiPhone5:
  326. case deviceiPhone5C:
  327. case deviceiPhone5S:
  328. case deviceiPhone6:
  329. case deviceiPhone6S:
  330. case deviceiPhoneSE1Gen:
  331. case deviceiPhone7:
  332. case deviceiPhone8:
  333. case deviceiPhoneXR:
  334. case deviceiPhone11:
  335. _DeviceDPI = 326.0f; break;
  336. case deviceiPhone6Plus:
  337. case deviceiPhone6SPlus:
  338. case deviceiPhone7Plus:
  339. case deviceiPhone8Plus:
  340. _DeviceDPI = 401.0f; break;
  341. case deviceiPhoneX:
  342. case deviceiPhoneXS:
  343. case deviceiPhoneXSMax:
  344. case deviceiPhone11Pro:
  345. case deviceiPhone11ProMax:
  346. _DeviceDPI = 458.0f; break;
  347. // iPad
  348. case deviceiPad2Gen:
  349. _DeviceDPI = 132.0f; break;
  350. case deviceiPad3Gen:
  351. case deviceiPad4Gen: // iPad retina
  352. case deviceiPadAir1:
  353. case deviceiPadAir2:
  354. case deviceiPadPro1Gen:
  355. case deviceiPadPro10Inch1Gen:
  356. case deviceiPadPro2Gen:
  357. case deviceiPadPro10Inch2Gen:
  358. case deviceiPad5Gen:
  359. case deviceiPad6Gen:
  360. case deviceiPadPro11Inch:
  361. case deviceiPadPro3Gen:
  362. _DeviceDPI = 264.0f; break;
  363. case deviceiPad7Gen:
  364. _DeviceDPI = 326.0f; break;
  365. // iPad mini
  366. case deviceiPadMini1Gen:
  367. _DeviceDPI = 163.0f; break;
  368. case deviceiPadMini2Gen:
  369. case deviceiPadMini3Gen:
  370. case deviceiPadMini4Gen:
  371. _DeviceDPI = 326.0f; break;
  372. // iPod
  373. case deviceiPodTouch4Gen:
  374. case deviceiPodTouch5Gen:
  375. case deviceiPodTouch6Gen:
  376. case deviceiPodTouch7Gen:
  377. _DeviceDPI = 326.0f; break;
  378. // unknown (new) devices
  379. case deviceiPhoneUnknown:
  380. _DeviceDPI = 326.0f; break;
  381. case deviceiPadUnknown:
  382. _DeviceDPI = 264.0f; break;
  383. case deviceiPodTouchUnknown:
  384. _DeviceDPI = 326.0f; break;
  385. }
  386. // If we didn't find DPI, set it to "unknown" value.
  387. if (_DeviceDPI < 0.0f)
  388. _DeviceDPI = 0.0f;
  389. }
  390. return _DeviceDPI;
  391. }
  392. // device id with fallback for pre-ios7
  393. extern "C" const char* UnityDeviceUniqueIdentifier()
  394. {
  395. static const char* _DeviceID = NULL;
  396. if (_DeviceID == NULL)
  397. _DeviceID = UnityVendorIdentifier();
  398. return _DeviceID;
  399. }