Commit 7eaa3cd81d966aaaa67c2a127796df5c2fe26e8d

David Ludwig 2014-01-01T16:05:37

WinRT: added a means to display a privacy policy link via the Settings charm This change is only relevant for Windows 8, 8.1, and RT apps, and only for those that are network-enabled. Such apps must feature a link to a privacy policy, which must be displayed via the Windows Settings charm. This is needed to pass Windows Store app-certification. Using SDL_SetHint, along with SDL_HINT_WINRT_PRIVACY_POLICY_URL and optionally SDL_HINT_WINRT_PRIVACY_POLICY_LABEL, will cause SDL/WinRT to create a link inside the Windows Settings charm, as invoked from within an SDL-based app. Network-enabled Windows Phone apps do not need to set this hint, and should provide some sort of in-app means to display their privacy policy. Microsoft does not appear to provide an OS-integrated means for displaying such on Windows Phone.

diff --git a/include/SDL_hints.h b/include/SDL_hints.h
index 9ca0097..57dc850 100644
--- a/include/SDL_hints.h
+++ b/include/SDL_hints.h
@@ -332,6 +332,53 @@ extern "C" {
 #define SDL_HINT_VIDEO_WIN_D3DCOMPILER              "SDL_VIDEO_WIN_D3DCOMPILER"
 
 /**
+ *  \brief A URL to a WinRT app's privacy policy
+ *
+ *  All network-enabled WinRT apps must make a privacy policy available to its
+ *  users.  On Windows 8, 8.1, and RT, Microsoft mandates that this policy be
+ *  be available in the Windows Settings charm, as accessed from within the app.
+ *  SDL provides code to add a URL-based link there, which can point to the app's
+ *  privacy policy.
+ *
+ *  To setup a URL to an app's privacy policy, set SDL_HINT_WINRT_PRIVACY_POLICY_URL
+ *  before calling any SDL_Init functions.  The contents of the hint should
+ *  be a valid URL.  For example, "http://www.example.com".
+ *
+ *  The default value is "", which will prevent SDL from adding a privacy policy
+ *  link to the Settings charm.  This hint should only be set during app init.
+ *
+ *  The label text of an app's "Privacy Policy" link may be customized via another
+ *  hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL.
+ *
+ *  Please note that on Windows Phone, Microsoft does not provide standard UI
+ *  for displaying a privacy policy link, and as such, SDL_HINT_WINRT_PRIVACY_POLICY_URL
+ *  will not get used on that platform.  Network-enabled phone apps should display
+ *  their privacy policy through some other, in-app means.
+ */
+#define SDL_HINT_WINRT_PRIVACY_POLICY_URL "SDL_HINT_WINRT_PRIVACY_POLICY_URL"
+
+/** \brief Label text for a WinRT app's privacy policy link
+ *
+ *  Network-enabled WinRT apps must include a privacy policy.  On Windows 8, 8.1, and RT,
+ *  Microsoft mandates that this policy be available via the Windows Settings charm.
+ *  SDL provides code to add a link there, with it's label text being set via the
+ *  optional hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL.
+ *
+ *  Please note that a privacy policy's contents are not set via this hint.  A separate
+ *  hint, SDL_HINT_WINRT_PRIVACY_POLICY_URL, is used to link to the actual text of the
+ *  policy.
+ *
+ *  The contents of this hint should be encoded as a UTF8 string.
+ *
+ *  The default value is "Privacy Policy".  This hint should only be set during app
+ *  initialization, preferably before any calls to SDL_Init.
+ *
+ *  For additional information on linking to a privacy policy, see the documentation for
+ *  SDL_HINT_WINRT_PRIVACY_POLICY_URL.
+ */
+#define SDL_HINT_WINRT_PRIVACY_POLICY_LABEL "SDL_HINT_WINRT_PRIVACY_POLICY_LABEL"
+
+/**
  *  \brief  An enumeration of hint priorities
  */
 typedef enum
diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp
index 05a7487..cb095e2 100644
--- a/src/core/winrt/SDL_winrtapp_direct3d.cpp
+++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp
@@ -34,6 +34,7 @@ extern "C" {
 #include "../../events/SDL_mouse_c.h"
 #include "../../events/SDL_windowevents_c.h"
 #include "../../render/SDL_sysrender.h"
+#include "../windows/SDL_windows.h"
 }
 
 #include "../../video/winrt/SDL_winrtevents_c.h"
@@ -314,6 +315,16 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window)
 
     window->KeyUp +=
         ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyUp);
+
+#if WINAPI_FAMILY == WINAPI_FAMILY_APP  // for Windows 8/8.1/RT apps... (and not Phone apps)
+    // Make sure we know when a user has opened the app's settings pane.
+    // This is needed in order to display a privacy policy, which needs
+    // to be done for network-enabled apps, as per Windows Store requirements.
+    using namespace Windows::UI::ApplicationSettings;
+    SettingsPane::GetForCurrentView()->CommandsRequested +=
+        ref new TypedEventHandler<SettingsPane^, SettingsPaneCommandsRequestedEventArgs^>
+            (this, &SDL_WinRTApp::OnSettingsPaneCommandsRequested);
+#endif
 }
 
 void SDL_WinRTApp::Load(Platform::String^ entryPoint)
@@ -352,6 +363,50 @@ void SDL_WinRTApp::Uninitialize()
 {
 }
 
+#if WINAPI_FAMILY == WINAPI_FAMILY_APP
+void SDL_WinRTApp::OnSettingsPaneCommandsRequested(
+    Windows::UI::ApplicationSettings::SettingsPane ^p,
+    Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args)
+{
+    using namespace Platform;
+    using namespace Windows::UI::ApplicationSettings;
+    using namespace Windows::UI::Popups;
+
+    String ^privacyPolicyURL = nullptr;     // a URL to an app's Privacy Policy
+    String ^privacyPolicyLabel = nullptr;   // label/link text
+    const char *tmpHintValue = NULL;        // SDL_GetHint-retrieved value, used immediately
+    wchar_t *tmpStr = NULL;                 // used for UTF8 to UCS2 conversion
+
+    // Setup a 'Privacy Policy' link, if one is available (via SDL_GetHint):
+    tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_URL);
+    if (tmpHintValue && tmpHintValue[0] != '\0') {
+        // Convert the privacy policy's URL to UCS2:
+        tmpStr = WIN_UTF8ToString(tmpHintValue);
+        privacyPolicyURL = ref new String(tmpStr);
+        SDL_free(tmpStr);
+
+        // Optionally retrieve custom label-text for the link.  If this isn't
+        // available, a default value will be used instead.
+        tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_LABEL);
+        if (tmpHintValue && tmpHintValue[0] != '\0') {
+            tmpStr = WIN_UTF8ToString(tmpHintValue);
+            privacyPolicyLabel = ref new String(tmpStr);
+            SDL_free(tmpStr);
+        } else {
+            privacyPolicyLabel = ref new String(L"Privacy Policy");
+        }
+
+        // Register the link, along with a handler to be called if and when it is
+        // clicked:
+        auto cmd = ref new SettingsCommand(L"privacyPolicy", privacyPolicyLabel,
+            ref new UICommandInvokedHandler([=](IUICommand ^) {
+                Windows::System::Launcher::LaunchUriAsync(ref new Uri(privacyPolicyURL));
+        }));
+        args->Request->ApplicationCommands->Append(cmd);
+    }
+}
+#endif // if WINAPI_FAMILY == WINAPI_FAMILY_APP
+
 void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
 {
 #if LOG_WINDOW_EVENTS==1
diff --git a/src/core/winrt/SDL_winrtapp_direct3d.h b/src/core/winrt/SDL_winrtapp_direct3d.h
index 837afdc..3aed74d 100644
--- a/src/core/winrt/SDL_winrtapp_direct3d.h
+++ b/src/core/winrt/SDL_winrtapp_direct3d.h
@@ -22,6 +22,13 @@ internal:
 
 protected:
     // Event Handlers.
+
+#if WINAPI_FAMILY == WINAPI_FAMILY_APP  // for Windows 8/8.1/RT apps... (and not Phone apps)
+    void OnSettingsPaneCommandsRequested(
+        Windows::UI::ApplicationSettings::SettingsPane ^p,
+        Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args);
+#endif // if WINAPI_FAMILY == WINAPI_FAMILY_APP
+
     void OnOrientationChanged(Platform::Object^ sender);
     void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args);
     void OnLogicalDpiChanged(Platform::Object^ sender);