UNPKG

25 kBtext/x-cView Raw
1#pragma once
2
3#include "pch.h"
4#include "NativeModules.h"
5#include <regex>
6#include <sstream>
7#include <chrono>
8#include <future>
9
10using namespace winrt::Microsoft::ReactNative;
11using namespace winrt::Windows::Foundation;
12
13namespace winrt::RNDeviceInfoCPP
14{
15 REACT_MODULE(RNDeviceInfoCPP, L"RNDeviceInfo");
16 struct RNDeviceInfoCPP
17 {
18 const std::string Name = "RNDeviceInfo";
19
20 ReactContext m_reactContext;
21 REACT_INIT(Initialize)
22 void Initialize(ReactContext const &reactContext) noexcept
23 {
24 m_reactContext = reactContext;
25 }
26
27 REACT_CONSTANT_PROVIDER(constantsViaConstantsProvider);
28 void constantsViaConstantsProvider(ReactConstantProvider& provider) noexcept
29 {
30 provider.Add(L"deviceId", getDeviceIdSync());
31 provider.Add(L"serialNumber", getSerialNumberSync());
32 provider.Add(L"bundleId", getBundleIdSync());
33 provider.Add(L"systemVersion", getSystemVersionSync());
34 provider.Add(L"appVersion", getAppVersionSync());
35 provider.Add(L"buildNumber", getBuildNumberSync());
36 provider.Add(L"isTablet", isTabletSync());
37 provider.Add(L"appName", getAppNameSync());
38 provider.Add(L"brand", getBrandSync());
39 provider.Add(L"model", getModelSync());
40 provider.Add(L"deviceType", getDeviceTypeSync());
41 provider.Add(L"supportedAbis", getSupportedAbisSync());
42 }
43
44 bool isEmulatorHelper(std::string model)
45 {
46 return std::regex_match(model, std::regex(".*virtual.*", std::regex_constants::icase));
47 }
48
49 // What is a tablet is a debateable topic in Windows, as some windows devices can dynamically switch back and forth.
50 // Also, see isTabletMode() instead of isTablet or deviceType.
51 // More refinement should be applied into this area as neccesary.
52 bool isTabletHelper()
53 {
54 // AnalyticsInfo doesn't always return the values one might expect.
55 // DeviceForm potential but not inclusive results:
56 // [Mobile, Tablet, Television, Car, Watch, VirtualReality, Desktop, Unknown]
57 // DeviceFamily potential but not inclusive results:
58 // [Windows.Desktop, Windows.Mobile, Windows.Xbox, Windows.Holographic, Windows.Team, Windows.IoT]
59 auto deviceForm = winrt::Windows::System::Profile::AnalyticsInfo::DeviceForm();
60 auto deviceFamily = winrt::Windows::System::Profile::AnalyticsInfo::VersionInfo().DeviceFamily();
61
62 bool isTabletByAnalytics = deviceForm == L"Tablet" || deviceForm == L"Mobile" || deviceFamily == L"Windows.Mobile";
63
64 if (isTabletByAnalytics)
65 {
66 return true;
67 }
68 return false;
69 }
70
71 IAsyncOperation<bool> isPinOrFingerprint()
72 {
73 try
74 {
75 auto ucAvailability = co_await Windows::Security::Credentials::UI::UserConsentVerifier::CheckAvailabilityAsync();
76 return ucAvailability == Windows::Security::Credentials::UI::UserConsentVerifierAvailability::Available;
77 }
78 catch (...)
79 {
80 return false;
81 }
82 }
83
84 REACT_SYNC_METHOD(getSupportedAbisSync);
85 JSValueArray getSupportedAbisSync() noexcept
86 {
87 JSValueArray result = JSValueArray{};
88 winrt::Windows::System::ProcessorArchitecture architecture =
89 winrt::Windows::ApplicationModel::Package::Current().Id().Architecture();
90 std::string arch;
91 switch (architecture)
92 {
93 case Windows::System::ProcessorArchitecture::X86:
94 arch = "win_x86";
95 break;
96 case Windows::System::ProcessorArchitecture::Arm:
97 arch = "win_arm";
98 break;
99 case Windows::System::ProcessorArchitecture::X64:
100 arch = "win_x64";
101 break;
102 case Windows::System::ProcessorArchitecture::Neutral:
103 arch = "neutral";
104 break;
105 default:
106 arch = "unknown";
107 break;
108 }
109 result.push_back(arch);
110 return result;
111 }
112
113 REACT_METHOD(getSupportedAbis)
114 void getSupportedAbis(ReactPromise<JSValueArray> promise) noexcept
115 {
116 promise.Resolve(getSupportedAbisSync());
117 }
118
119 REACT_SYNC_METHOD(getDeviceTypeSync);
120 std::string getDeviceTypeSync() noexcept
121 {
122 if (isTabletHelper())
123 {
124 return "Tablet";
125 }
126 else if (winrt::Windows::System::Profile::AnalyticsInfo::VersionInfo().DeviceFamily() == L"Windows.Xbox")
127 {
128 return "GamingConsole";
129 }
130 else
131 {
132 return "Desktop";
133 }
134 }
135
136 REACT_METHOD(getDeviceType);
137 void getDeviceType(ReactPromise<std::string> promise) noexcept
138 {
139 promise.Resolve(getDeviceTypeSync());
140 }
141
142 REACT_SYNC_METHOD(isPinOrFingerprintSetSync);
143 bool isPinOrFingerprintSetSync() noexcept
144 {
145 return isPinOrFingerprint().get();
146 }
147
148 REACT_METHOD(isPinOrFingerprintSet);
149 void isPinOrFingerprintSet(ReactPromise<bool> promise) noexcept
150 {
151 auto async_op = isPinOrFingerprint();
152 async_op.Completed([promise](auto const& op, auto const&)
153 {
154 promise.Resolve(op.GetResults());
155 });
156 }
157
158 REACT_SYNC_METHOD(isKeyboardConnectedSync);
159 bool isKeyboardConnectedSync() noexcept
160 {
161 auto keyboardCapabilities = winrt::Windows::Devices::Input::KeyboardCapabilities();
162 return keyboardCapabilities.KeyboardPresent();
163 }
164
165 REACT_METHOD(isKeyboardConnected);
166 void isKeyboardConnected(ReactPromise<bool> promise) noexcept
167 {
168 promise.Resolve(isKeyboardConnectedSync());
169 }
170
171 REACT_SYNC_METHOD(isMouseConnectedSync);
172 bool isMouseConnectedSync() noexcept
173 {
174 auto mouseCapabilities = winrt::Windows::Devices::Input::MouseCapabilities();
175 return mouseCapabilities.MousePresent();
176 }
177
178 REACT_METHOD(isMouseConnected);
179 void isMouseConnected(ReactPromise<bool> promise) noexcept
180 {
181 promise.Resolve(isMouseConnectedSync());
182 }
183
184 REACT_METHOD(isTabletMode);
185 void isTabletMode(ReactPromise<bool> promise) noexcept
186 {
187 // NOTE: Should eventually add IsXamlIsland() relevant code when it's exposed through RNW's public API.
188
189 m_reactContext.UIDispatcher().Post([promise]() {
190 auto view = winrt::Windows::UI::ViewManagement::UIViewSettings::GetForCurrentView();
191 auto mode = view.UserInteractionMode();
192 switch(mode)
193 {
194 case winrt::Windows::UI::ViewManagement::UserInteractionMode::Touch:
195 {
196 promise.Resolve(true);
197 return;
198 }
199 case winrt::Windows::UI::ViewManagement::UserInteractionMode::Mouse:
200 default:
201 {
202 promise.Resolve(false);
203 }
204 } });
205 }
206
207 REACT_SYNC_METHOD(getIpAddressSync);
208 std::string getIpAddressSync() noexcept
209 {
210 auto icp = Windows::Networking::Connectivity::NetworkInformation::GetInternetConnectionProfile();
211 if (!icp || !icp.NetworkAdapter())
212 {
213 return "unknown";
214 }
215 else
216 {
217 auto hostnames = Windows::Networking::Connectivity::NetworkInformation::GetHostNames();
218 for (auto const& hostname : hostnames)
219 {
220 if (
221 hostname.Type() == Windows::Networking::HostNameType::Ipv4 &&
222 hostname.IPInformation() &&
223 hostname.IPInformation().NetworkAdapter() &&
224 hostname.IPInformation().NetworkAdapter().NetworkAdapterId() == icp.NetworkAdapter().NetworkAdapterId())
225 {
226 return winrt::to_string(hostname.CanonicalName());
227 }
228 }
229 return "unknown";
230 }
231 }
232
233 REACT_METHOD(getIpAddress);
234 void getIpAddress(ReactPromise<std::string> promise) noexcept
235 {
236 promise.Resolve(getIpAddressSync());
237 }
238
239 IAsyncOperation<bool> isCameraPresentTask()
240 {
241 Windows::Devices::Enumeration::DeviceInformationCollection devices =
242 co_await Windows::Devices::Enumeration::DeviceInformation::FindAllAsync(Windows::Devices::Enumeration::DeviceClass::VideoCapture);
243
244 return devices.Size() > 0;
245 }
246
247 REACT_SYNC_METHOD(isCameraPresentSync);
248 bool isCameraPresentSync() noexcept
249 {
250 return isCameraPresentTask().get();
251 }
252
253 REACT_METHOD(isCameraPresent);
254 void isCameraPresent(ReactPromise<bool> promise) noexcept
255 {
256 auto async_op = isCameraPresentTask();
257 async_op.Completed([promise](auto const& op, auto const&)
258 {
259 promise.Resolve(op.GetResults());
260 });
261 }
262
263 REACT_SYNC_METHOD(getBatteryLevelSync);
264 double getBatteryLevelSync() noexcept
265 {
266 auto aggBattery = Windows::Devices::Power::Battery::AggregateBattery();
267 auto report = aggBattery.GetReport();
268 if (report.FullChargeCapacityInMilliwattHours() == nullptr ||
269 report.RemainingCapacityInMilliwattHours() == nullptr)
270 {
271 return (double)-1;
272 }
273 else
274 {
275 auto max = report.FullChargeCapacityInMilliwattHours().GetDouble();
276 auto value = report.RemainingCapacityInMilliwattHours().GetDouble();
277 if (max <= 0)
278 {
279 return (double)-1;
280 }
281 else
282 {
283 return value / max;
284 }
285 }
286 }
287
288 REACT_METHOD(getBatteryLevel);
289 void getBatteryLevel(ReactPromise<double> promise) noexcept
290 {
291 promise.Resolve(getBatteryLevelSync());
292 }
293
294 REACT_SYNC_METHOD(getPowerStateSync);
295 JSValue getPowerStateSync() noexcept
296 {
297 JSValueObject result = JSValueObject{};
298 const std::string states[4] = { "not present", "discharging", "idle", "charging" };
299 auto aggBattery = Windows::Devices::Power::Battery::AggregateBattery();
300 auto report = aggBattery.GetReport();
301 if (report.FullChargeCapacityInMilliwattHours() != nullptr &&
302 report.RemainingCapacityInMilliwattHours() != nullptr)
303 {
304 auto max = report.FullChargeCapacityInMilliwattHours().GetDouble();
305 auto value = report.RemainingCapacityInMilliwattHours().GetDouble();
306 if (max <= 0)
307 {
308 result["batteryLevel"] = (double)-1;
309 }
310 else
311 {
312 result["batteryLevel"] = value / max;
313 }
314 result["batteryState"] = states[static_cast<int>(report.Status())];
315 result["lowPowerMode"] = (Windows::System::Power::PowerManager::EnergySaverStatus() == Windows::System::Power::EnergySaverStatus::On);
316 }
317
318 return result;
319 }
320
321 REACT_METHOD(getPowerState);
322 void getPowerState(ReactPromise<JSValue> promise) noexcept
323 {
324 promise.Resolve(getPowerStateSync());
325 }
326
327 REACT_SYNC_METHOD(isBatteryChargingSync);
328 bool isBatteryChargingSync() noexcept
329 {
330 auto aggBattery = Windows::Devices::Power::Battery::AggregateBattery();
331 auto report = aggBattery.GetReport();
332 return report.Status() == Windows::System::Power::BatteryStatus::Charging;
333 }
334
335 REACT_METHOD(isBatteryCharging);
336 void isBatteryCharging(ReactPromise<bool> promise) noexcept
337 {
338 promise.Resolve(isBatteryChargingSync());
339 }
340
341 REACT_SYNC_METHOD(getAppVersionSync);
342 std::string getAppVersionSync() noexcept
343 {
344 try
345 {
346 Windows::ApplicationModel::PackageVersion version = Windows::ApplicationModel::Package::Current().Id().Version();
347
348 std::ostringstream ostream;
349 ostream << version.Major << "." << version.Minor << "." << version.Build << "." << version.Revision;
350 return ostream.str();
351 } catch (...)
352 {
353 return "unknown";
354 }
355 }
356
357 REACT_METHOD(getAppVersion);
358 void getAppVersion(ReactPromise<std::string> promise) noexcept
359 {
360 promise.Resolve(getAppVersionSync());
361 }
362
363 REACT_SYNC_METHOD(getBuildNumberSync);
364 std::string getBuildNumberSync() noexcept
365 {
366 try
367 {
368 return std::to_string(Windows::ApplicationModel::Package::Current().Id().Version().Build);
369 } catch (...)
370 {
371 return "unknown";
372 }
373 }
374 REACT_METHOD(getBuildNumber);
375 void getBuildNumber(ReactPromise<std::string> promise) noexcept
376 {
377 promise.Resolve(getBuildNumberSync());
378 }
379
380 REACT_SYNC_METHOD(getBuildVersionSync);
381 std::string getBuildVersionSync() noexcept
382 {
383 return getBuildNumberSync();
384 }
385
386 REACT_METHOD(getBuildVersion);
387 void getBuildVersion(ReactPromise<std::string> promise) noexcept
388 {
389 promise.Resolve(getBuildVersionSync());
390 }
391
392 REACT_SYNC_METHOD(getInstallerPackageNameSync);
393 std::string getInstallerPackageNameSync() noexcept
394 {
395 try
396 {
397 return winrt::to_string(Windows::ApplicationModel::Package::Current().Id().Name());
398 } catch (...)
399 {
400 return "unknown";
401 }
402 }
403 REACT_METHOD(getInstallerPackageName);
404 void getInstallerPackageName(ReactPromise<std::string> promise) noexcept
405 {
406 promise.Resolve(getInstallerPackageNameSync());
407 }
408
409 REACT_SYNC_METHOD(getInstallReferrerSync);
410 std::string getInstallReferrerSync() noexcept
411 {
412 try
413 {
414 Windows::Services::Store::StoreContext context = Windows::Services::Store::StoreContext::GetDefault();
415
416 // Get campaign ID for users with a recognized Microsoft account.
417 Windows::Services::Store::StoreProductResult result = context.GetStoreProductForCurrentAppAsync().get();
418 if (result.Product() != nullptr)
419 {
420 for (auto sku : result.Product().Skus())
421 {
422 if (sku.IsInUserCollection())
423 {
424 return winrt::to_string(sku.CollectionData().CampaignId());
425 }
426 }
427 }
428
429 // Get campaing ID from the license data for users without a recognized Microsoft account.
430 Windows::Services::Store::StoreAppLicense license = context.GetAppLicenseAsync().get();
431 auto json = Windows::Data::Json::JsonObject::Parse(license.ExtendedJsonData());
432 if (json.HasKey(L"customPolicyField1"))
433 {
434 return winrt::to_string(json.GetNamedString(L"customPolicyField1", L"unknown"));
435 }
436
437 } catch (...)
438 {
439 }
440 return "unknown";
441 }
442 REACT_METHOD(getInstallReferrer);
443 void getInstallReferrer(ReactPromise<std::string> promise) noexcept
444 {
445 promise.Resolve(getInstallReferrerSync());
446 }
447
448 REACT_SYNC_METHOD(getMaxMemorySync);
449 uint64_t getMaxMemorySync() noexcept
450 {
451 return Windows::System::MemoryManager::AppMemoryUsageLimit();
452 }
453
454 REACT_METHOD(getMaxMemory);
455 void getMaxMemory(ReactPromise<uint64_t> promise) noexcept
456 {
457 promise.Resolve(getMaxMemorySync());
458 }
459
460 REACT_SYNC_METHOD(getUsedMemorySync);
461 uint64_t getUsedMemorySync() noexcept
462 {
463 return Windows::System::MemoryManager::AppMemoryUsage();
464 }
465
466 REACT_METHOD(getUsedMemory);
467 void getUsedMemory(ReactPromise<uint64_t> promise) noexcept
468 {
469 promise.Resolve(getUsedMemorySync());
470 }
471
472 REACT_SYNC_METHOD(getFirstInstallTimeSync);
473 int64_t getFirstInstallTimeSync() noexcept
474 {
475 auto installTime = Windows::ApplicationModel::Package::Current().InstalledDate().time_since_epoch();
476 return std::chrono::duration_cast<std::chrono::milliseconds>(installTime).count();
477 }
478
479 REACT_METHOD(getFirstInstallTime);
480 void getFirstInstallTime(ReactPromise<int64_t> promise) noexcept
481 {
482 promise.Resolve(getFirstInstallTimeSync());
483 }
484
485 REACT_SYNC_METHOD(getAppNameSync);
486 std::string getAppNameSync() noexcept
487 {
488 return winrt::to_string(Windows::ApplicationModel::Package::Current().DisplayName());
489 }
490
491 REACT_METHOD(getAppName);
492 void getAppName(ReactPromise<std::string> promise) noexcept
493 {
494 promise.Resolve(getAppNameSync());
495 }
496
497 REACT_SYNC_METHOD(getBundleIdSync);
498 std::string getBundleIdSync() noexcept
499 {
500 return winrt::to_string(Windows::ApplicationModel::Package::Current().Id().Name());
501 }
502
503 REACT_METHOD(getBundleId);
504 void getBundleId(ReactPromise<std::string> promise) noexcept
505 {
506 promise.Resolve(getBundleIdSync());
507 }
508
509 REACT_SYNC_METHOD(getDeviceNameSync);
510 std::string getDeviceNameSync() noexcept
511 {
512 try
513 {
514 return winrt::to_string(Windows::Security::ExchangeActiveSyncProvisioning::EasClientDeviceInformation().FriendlyName());
515 } catch (...)
516 {
517 return "unknown";
518 }
519 }
520
521 REACT_METHOD(getDeviceName);
522 void getDeviceName(ReactPromise<std::string> promise) noexcept
523 {
524 promise.Resolve(getDeviceNameSync());
525 }
526
527 REACT_SYNC_METHOD(getSystemVersionSync);
528 std::string getSystemVersionSync() noexcept
529 {
530 try
531 {
532 std::string deviceFamilyVersion = winrt::to_string(Windows::System::Profile::AnalyticsInfo::VersionInfo().DeviceFamilyVersion());
533 uint64_t version2 = std::stoull(deviceFamilyVersion);
534 uint64_t major = (version2 & 0xFFFF000000000000L) >> 48;
535 uint64_t minor = (version2 & 0x0000FFFF00000000L) >> 32;
536 std::ostringstream ostream;
537 ostream << major << "." << minor;
538 return ostream.str();
539 }
540 catch (...)
541 {
542 return "unknown";
543 }
544 }
545
546 REACT_METHOD(getSystemVersion);
547 void getSystemVersion(ReactPromise<std::string> promise) noexcept
548 {
549 promise.Resolve(getSystemVersionSync());
550 }
551
552 REACT_SYNC_METHOD(getBaseOsSync);
553 std::string getBaseOsSync() noexcept
554 {
555 try
556 {
557 std::string deviceFamilyVersion = winrt::to_string(Windows::System::Profile::AnalyticsInfo::VersionInfo().DeviceFamilyVersion());
558 uint64_t version2 = std::stoull(deviceFamilyVersion);
559 uint64_t major = (version2 & 0xFFFF000000000000L) >> 48;
560 uint64_t minor = (version2 & 0x0000FFFF00000000L) >> 32;
561 uint64_t build = (version2 & 0x00000000FFFF0000L) >> 16;
562 uint64_t revision = (version2 & 0x000000000000FFFFL);
563 std::ostringstream ostream;
564 ostream << major << "." << minor << "." << build << "." << revision;
565 return ostream.str();
566 }
567 catch (...)
568 {
569 return "unknown";
570 }
571 }
572
573 REACT_METHOD(getBaseOs);
574 void getBaseOs(ReactPromise<std::string> promise) noexcept
575 {
576 promise.Resolve(getBaseOsSync());
577 }
578
579 REACT_SYNC_METHOD(getBuildIdSync);
580 std::string getBuildIdSync() noexcept
581 {
582 try
583 {
584 std::string deviceFamilyVersion = winrt::to_string(Windows::System::Profile::AnalyticsInfo::VersionInfo().DeviceFamilyVersion());
585 uint64_t version2 = std::stoull(deviceFamilyVersion);
586 uint64_t build = (version2 & 0x00000000FFFF0000L) >> 16;
587 std::ostringstream ostream;
588 ostream << build;
589 return ostream.str();
590 }
591 catch (...)
592 {
593 return "unknown";
594 }
595 }
596
597 REACT_METHOD(getBuildId);
598 void getBuildId(ReactPromise<std::string> promise) noexcept
599 {
600 promise.Resolve(getBuildIdSync());
601 }
602
603 REACT_SYNC_METHOD(getModelSync);
604 std::string getModelSync() noexcept
605 {
606 try
607 {
608 return winrt::to_string(Windows::Security::ExchangeActiveSyncProvisioning::EasClientDeviceInformation().SystemProductName());
609 }
610 catch (...)
611 {
612 return "unknown";
613 }
614 }
615
616 REACT_METHOD(getModel);
617 void getModel(ReactPromise<std::string> promise) noexcept
618 {
619 promise.Resolve(getModelSync());
620 }
621
622 REACT_SYNC_METHOD(getBrandSync);
623 std::string getBrandSync() noexcept
624 {
625 return getModelSync();
626 }
627
628 REACT_METHOD(getBrand);
629 void getBrand(ReactPromise<std::string> promise) noexcept
630 {
631 promise.Resolve(getBrandSync());
632 }
633
634 REACT_SYNC_METHOD(isEmulatorSync);
635 bool isEmulatorSync() noexcept
636 {
637 try
638 {
639 auto deviceInfo = Windows::Security::ExchangeActiveSyncProvisioning::EasClientDeviceInformation();
640 return winrt::to_string(deviceInfo.SystemProductName()) == "Virtual";
641 } catch (...)
642 {
643 return false;
644 }
645 }
646
647 REACT_METHOD(isEmulator);
648 void isEmulator(ReactPromise<bool> promise) noexcept
649 {
650 promise.Resolve(isEmulatorSync());
651 }
652
653 REACT_SYNC_METHOD(getUniqueIdSync);
654 std::string getUniqueIdSync() noexcept
655 {
656 try
657 {
658 return winrt::to_string(winrt::to_hstring(Windows::Security::ExchangeActiveSyncProvisioning::EasClientDeviceInformation().Id()));
659 } catch (...)
660 {
661 return "unknown";
662 }
663 }
664
665 REACT_METHOD(getUniqueId);
666 void getUniqueId(ReactPromise<std::string> promise) noexcept
667 {
668 promise.Resolve(getUniqueIdSync());
669 }
670
671 REACT_SYNC_METHOD(getDeviceIdSync);
672 std::string getDeviceIdSync() noexcept
673 {
674 try
675 {
676 return winrt::to_string(Windows::Security::ExchangeActiveSyncProvisioning::EasClientDeviceInformation().SystemSku());
677 } catch (...)
678 {
679 return "unknown";
680 }
681 }
682
683 REACT_METHOD(getDeviceId);
684 void getDeviceId(ReactPromise<std::string> promise) noexcept
685 {
686 promise.Resolve(getDeviceIdSync());
687 }
688
689 REACT_SYNC_METHOD(getSerialNumberSync);
690 std::string getSerialNumberSync() noexcept
691 {
692 try
693 {
694 return winrt::to_string(Windows::System::Profile::SystemManufacturers::SmbiosInformation::SerialNumber().c_str());
695 }
696 catch (...)
697 {
698 return "unknown";
699 }
700 }
701
702 REACT_METHOD(getSerialNumber);
703 void getSerialNumber(ReactPromise<std::string> promise) noexcept
704 {
705 promise.Resolve(getSerialNumberSync());
706 }
707
708 REACT_SYNC_METHOD(getSystemManufacturerSync);
709 std::string getSystemManufacturerSync() noexcept
710 {
711 try
712 {
713 return winrt::to_string(Windows::Security::ExchangeActiveSyncProvisioning::EasClientDeviceInformation().SystemManufacturer());
714 } catch (...)
715 {
716 return "unknown";
717 }
718 }
719
720 REACT_METHOD(getSystemManufacturer);
721 void getSystemManufacturer(ReactPromise<std::string> promise) noexcept
722 {
723 promise.Resolve(getSystemManufacturerSync());
724 }
725
726 REACT_SYNC_METHOD(isTabletSync);
727 bool isTabletSync() noexcept
728 {
729 try
730 {
731 return isTabletHelper();
732 } catch (...)
733 {
734 return false;
735 }
736 }
737
738 REACT_METHOD(isTablet);
739 void isTablet(ReactPromise<bool> promise) noexcept
740 {
741 promise.Resolve(isTabletSync());
742 }
743
744 REACT_SYNC_METHOD(getTotalMemorySync);
745 int64_t getTotalMemorySync() noexcept
746 {
747 // Device memory is not available through winrt APIs.
748 return -1;
749 }
750
751 REACT_METHOD(getTotalMemory);
752 void getTotalMemory(ReactPromise<int64_t> promise) noexcept
753 {
754 promise.Resolve(getTotalMemorySync());
755 }
756
757 REACT_SYNC_METHOD(getFontScaleSync);
758 double getFontScaleSync() noexcept
759 {
760 Windows::UI::ViewManagement::UISettings uiSettings;
761 return uiSettings.TextScaleFactor();
762 }
763
764 REACT_METHOD(getFontScale);
765 void getFontScale(ReactPromise<double> promise) noexcept
766 {
767 promise.Resolve(getFontScaleSync());
768 }
769
770 IAsyncOperation<int64_t> getFreeDiskStorageTask()
771 {
772 try
773 {
774 auto localFolder = Windows::Storage::ApplicationData::Current().LocalFolder();
775 auto props = co_await localFolder.Properties().RetrievePropertiesAsync({ L"System.FreeSpace" });
776 return winrt::unbox_value<uint64_t>(props.Lookup(L"System.FreeSpace"));
777 } catch (...)
778 {
779 co_return -1;
780 }
781 }
782
783 REACT_SYNC_METHOD(getFreeDiskStorageSync);
784 int64_t getFreeDiskStorageSync() noexcept
785 {
786 return getFreeDiskStorageTask().get();
787 }
788
789 REACT_METHOD(getFreeDiskStorage);
790 void getFreeDiskStorage(ReactPromise<int64_t> promise) noexcept
791 {
792 auto async_op = getFreeDiskStorageTask();
793 async_op.Completed([promise](auto const& op, auto const&)
794 {
795 promise.Resolve(op.GetResults());
796 });
797 }
798
799 IAsyncOperation<int64_t> getTotalDiskCapacityTask()
800 {
801 try
802 {
803 auto localFolder = Windows::Storage::ApplicationData::Current().LocalFolder();
804 auto props = co_await localFolder.Properties().RetrievePropertiesAsync({ L"System.Capacity" });
805 return winrt::unbox_value<uint64_t>(props.Lookup(L"System.Capacity"));
806 } catch (...)
807 {
808 co_return -1;
809 }
810 }
811
812 REACT_SYNC_METHOD(getTotalDiskCapacitySync);
813 int64_t getTotalDiskCapacitySync() noexcept
814 {
815 return getTotalDiskCapacityTask().get();
816 }
817
818 REACT_METHOD(getTotalDiskCapacity);
819 void getTotalDiskCapacity(ReactPromise<int64_t> promise) noexcept
820 {
821 auto async_op = getTotalDiskCapacityTask();
822 async_op.Completed([promise](auto const& op, auto const&)
823 {
824 promise.Resolve(op.GetResults());
825 });
826 }
827
828 REACT_METHOD(addListener);
829 void addListener(std::string) noexcept
830 {
831 // Keep: Required for RN built in Event Emitter Calls.
832 }
833
834 REACT_METHOD(removeListeners);
835 void removeListeners(int64_t) noexcept
836 {
837 // Keep: Required for RN built in Event Emitter Calls.
838 }
839 };
840
841}