diff --git a/support/hololens/ServoApp/BrowserPage.cpp b/support/hololens/ServoApp/BrowserPage.cpp
index 95265852b92..2cf98b7452b 100644
--- a/support/hololens/ServoApp/BrowserPage.cpp
+++ b/support/hololens/ServoApp/BrowserPage.cpp
@@ -18,6 +18,23 @@ namespace winrt::ServoApp::implementation {
BrowserPage::BrowserPage() {
InitializeComponent();
BindServoEvents();
+ if (!xrPkgChecker.IsInstalled()) {
+ XRPkgWarning().Visibility(Visibility::Visible);
+ xrPkgChecker.OnInstalled(
+ [=] { XRPkgWarning().Visibility(Visibility::Collapsed); },
+ std::chrono::seconds{5});
+ }
+}
+
+void BrowserPage::OnXRPkgWarningDismissClick(IInspectable const &,
+ RoutedEventArgs const &) {
+ xrPkgChecker.StopTracking();
+ XRPkgWarning().Visibility(Visibility::Collapsed);
+}
+
+void BrowserPage::OnXRPkgWarningInstallClick(IInspectable const &,
+ RoutedEventArgs const &) {
+ xrPkgChecker.OpenStore();
}
void BrowserPage::BindServoEvents() {
diff --git a/support/hololens/ServoApp/BrowserPage.h b/support/hololens/ServoApp/BrowserPage.h
index 6c1af3f9059..f4585fd8321 100644
--- a/support/hololens/ServoApp/BrowserPage.h
+++ b/support/hololens/ServoApp/BrowserPage.h
@@ -5,6 +5,7 @@
#pragma once
#include "BrowserPage.g.h"
+#include "XRPkgChecker.h"
#include "ServoControl\ServoControl.h"
namespace winrt::ServoApp::implementation {
@@ -34,9 +35,14 @@ public:
void LoadServoURI(Windows::Foundation::Uri uri);
void SetTransientMode(bool);
void SetArgs(hstring);
+ void OnXRPkgWarningInstallClick(Windows::Foundation::IInspectable const &,
+ Windows::UI::Xaml::RoutedEventArgs const &);
+ void OnXRPkgWarningDismissClick(Windows::Foundation::IInspectable const &,
+ Windows::UI::Xaml::RoutedEventArgs const &);
private:
void BindServoEvents();
+ XRPkgChecker xrPkgChecker;
};
} // namespace winrt::ServoApp::implementation
diff --git a/support/hololens/ServoApp/BrowserPage.xaml b/support/hololens/ServoApp/BrowserPage.xaml
index f4fe39c8acb..9990c0dab6c 100644
--- a/support/hololens/ServoApp/BrowserPage.xaml
+++ b/support/hololens/ServoApp/BrowserPage.xaml
@@ -84,6 +84,7 @@
+
@@ -126,5 +127,12 @@
+
+ The package "Windows OpenXR Developer Preview" is not installed. WebXR pages won't work.
+
+
+
+
+
diff --git a/support/hololens/ServoApp/Package.appxmanifest b/support/hololens/ServoApp/Package.appxmanifest
index 0a74082b073..c366444f8f0 100644
--- a/support/hololens/ServoApp/Package.appxmanifest
+++ b/support/hololens/ServoApp/Package.appxmanifest
@@ -1,5 +1,11 @@
-
+
@@ -44,6 +50,7 @@
+
diff --git a/support/hololens/ServoApp/ServoApp.vcxproj b/support/hololens/ServoApp/ServoApp.vcxproj
index 1a5bd6452cb..e3869ca1f97 100644
--- a/support/hololens/ServoApp/ServoApp.vcxproj
+++ b/support/hololens/ServoApp/ServoApp.vcxproj
@@ -133,6 +133,7 @@
+
@@ -928,6 +929,7 @@
+
diff --git a/support/hololens/ServoApp/ServoApp.vcxproj.filters b/support/hololens/ServoApp/ServoApp.vcxproj.filters
index 13eb4b1b423..06630e046af 100644
--- a/support/hololens/ServoApp/ServoApp.vcxproj.filters
+++ b/support/hololens/ServoApp/ServoApp.vcxproj.filters
@@ -22,6 +22,7 @@
ServoControl
+
@@ -38,6 +39,7 @@
ServoControl
+
diff --git a/support/hololens/ServoApp/XRPkgChecker.cpp b/support/hololens/ServoApp/XRPkgChecker.cpp
new file mode 100644
index 00000000000..4bdb2b5a71d
--- /dev/null
+++ b/support/hololens/ServoApp/XRPkgChecker.cpp
@@ -0,0 +1,52 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+#include "pch.h"
+#include "XRPkgChecker.h"
+#include "logs.h"
+#include "winrt/Windows.Management.Deployment.h"
+
+using namespace winrt::Windows::Management::Deployment;
+
+namespace winrt {
+
+void XRPkgChecker::OnInstalled(std::function callback,
+ winrt::Windows::Foundation::TimeSpan interval) {
+ timer.Stop();
+ timer.Interval(interval);
+ installed_callback = std::make_unique>(callback);
+ timer.Tick({this, &XRPkgChecker::CheckXRPkgTick});
+ timer.Start();
+}
+
+void XRPkgChecker::StopTracking() {
+ installed_callback.reset();
+ timer.Stop();
+}
+
+void XRPkgChecker::CheckXRPkgTick(Windows::Foundation::IInspectable const &,
+ Windows::Foundation::IInspectable const &) {
+ if (IsInstalled()) {
+ (*installed_callback)();
+ StopTracking();
+ }
+}
+
+void XRPkgChecker::OpenStore() {
+ std::wstring url = L"ms-windows-store://pdp/?PFN=";
+ Windows::Foundation::Uri uri{url + OPENXR_PACKAGE_NAME};
+ Windows::System::Launcher::LaunchUriAsync(uri);
+}
+
+bool XRPkgChecker::IsInstalled() {
+ auto current_user = L"";
+ for (auto package : PackageManager().FindPackagesForUser(current_user)) {
+ if (package.Id().Name() == OPENXR_PACKAGE_SHORT_NAME) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace winrt
diff --git a/support/hololens/ServoApp/XRPkgChecker.h b/support/hololens/ServoApp/XRPkgChecker.h
new file mode 100644
index 00000000000..84a7c6ff843
--- /dev/null
+++ b/support/hololens/ServoApp/XRPkgChecker.h
@@ -0,0 +1,30 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+#pragma once
+
+#include "pch.h"
+
+namespace winrt {
+class XRPkgChecker {
+
+public:
+ void OnInstalled(std::function callback,
+ winrt::Windows::Foundation::TimeSpan interval);
+ bool IsInstalled();
+ void StopTracking();
+ void OpenStore();
+
+private:
+ std::unique_ptr> installed_callback;
+ void CheckXRPkgTick(Windows::Foundation::IInspectable const &,
+ Windows::Foundation::IInspectable const &);
+ Windows::UI::Xaml::DispatcherTimer timer;
+ inline static const hstring OPENXR_PACKAGE_NAME =
+ L"Microsoft.MixedRealityRuntimeDeveloperPreview_8wekyb3d8bbwe";
+ inline static const hstring OPENXR_PACKAGE_SHORT_NAME =
+ L"Microsoft.MixedRealityRuntimeDeveloperPreview";
+};
+
+} // namespace winrt