Bug 1618094 Use SchemeSupported dbus method to check if system supports scheme; r=stransky
authorJan Horak <jhorak@redhat.com>
Thu, 24 Oct 2024 08:07:49 +0000 (8 months ago)
changeset 759471 9cdd0a07644d02d64c67270f70636bb654a8248e
parent 759470 1fd874fb28a2db5c84df8126967b1d668856cbb9
child 759472 084a45f6eb4fd1de6f0f5b19a4225ac33ad00057
push id216660
push userarchaeopteryx@coole-files.de
push dateThu, 24 Oct 2024 08:23:30 +0000 (8 months ago)
treeherderautoland@9cdd0a07644d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersstransky
bugs1618094
milestone133.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1618094 Use SchemeSupported dbus method to check if system supports scheme; r=stransky The SchemeSupported has been added to the org.freedesktop.portal.OpenURI interface. That should fix problems with wrong uri scheme handling by checking whenever system is able to open specified scheme. Differential Revision: https://phabricator.services.mozilla.com/D225771
toolkit/system/gnome/nsGIOService.cpp
--- a/toolkit/system/gnome/nsGIOService.cpp
+++ b/toolkit/system/gnome/nsGIOService.cpp
@@ -29,16 +29,25 @@
 #  include <fcntl.h>
 #  include <dlfcn.h>
 #  include "mozilla/widget/AsyncDBus.h"
 #  include "mozilla/WidgetUtilsGtk.h"
 #endif
 
 using namespace mozilla;
 
+#ifdef MOZ_LOGGING
+#  include "mozilla/Logging.h"
+LazyLogModule gGIOServiceLog("GIOService");
+#  define LOG(...) \
+    MOZ_LOG(gGIOServiceLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
+#else
+#  define LOG(...)
+#endif /* MOZ_LOGGING */
+
 class nsFlatpakHandlerApp : public nsIHandlerApp {
  public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIHANDLERAPP
   nsFlatpakHandlerApp() = default;
 
  private:
   virtual ~nsFlatpakHandlerApp() = default;
@@ -585,33 +594,85 @@ nsGIOService::GetMimeTypeFromExtension(c
     return NS_ERROR_FAILURE;
   }
 
   aMimeType.Assign(mime_type.get());
   return NS_OK;
 }
 // used in nsGNOMERegistry
 // -----------------------------------------------------------------------------
+#define OPENURI_BUS_NAME "org.freedesktop.portal.Desktop"
+#define OPENURI_OBJECT_PATH "/org/freedesktop/portal/desktop"
+#define OPENURI_INTERFACE_NAME "org.freedesktop.portal.OpenURI"
+#define SCHEME_SUPPORTED_METHOD "SchemeSupported"
+
 NS_IMETHODIMP
 nsGIOService::GetAppForURIScheme(const nsACString& aURIScheme,
                                  nsIHandlerApp** aApp) {
   *aApp = nullptr;
 
   // Application in flatpak sandbox does not have access to the list
-  // of installed applications on the system. We use generic
-  // nsFlatpakHandlerApp which forwards launch call to the system.
+  // of installed applications on the system. We use SchemeSupported
+  // method to check if the URI scheme is supported and then use
+  // generic nsFlatpakHandlerApp which forwards launch call to the system.
   if (widget::ShouldUsePortal(widget::PortalKind::MimeHandler)) {
     if (mozilla::net::IsLoopbackHostname(aURIScheme)) {
       // When the user writes foo:1234, we try to handle it natively using
       // GetAppForURIScheme, and if that fails, we carry on. On flatpak there's
       // no way to know if an app has handlers or not. Some things like
       // localhost:1234 are really unlikely to be handled by native
       // apps, and we're much better off returning an error here instead.
       return NS_ERROR_FAILURE;
     }
+    GUniquePtr<GError> error;
+    RefPtr<GDBusProxy> proxy;
+    RefPtr<GVariant> result;
+
+    proxy = g_dbus_proxy_new_for_bus_sync(
+        G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, nullptr, OPENURI_BUS_NAME,
+        OPENURI_OBJECT_PATH, OPENURI_INTERFACE_NAME,
+        nullptr,  // cancellable
+        getter_Transfers(error));
+    if (error) {
+      g_warning("Failed to create proxy: %s\n", error->message);
+      return NS_ERROR_FAILURE;
+    }
+    // Construct the dictionary of options (empty in current implementaiton)
+    GVariantBuilder builder;
+    g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
+
+    result = dont_AddRef(g_dbus_proxy_call_sync(
+        proxy, SCHEME_SUPPORTED_METHOD,
+        g_variant_new("(sa{sv})", PromiseFlatCString(aURIScheme).get(),
+                      &builder),
+        G_DBUS_CALL_FLAGS_NONE,
+        -1,       // timeout
+        nullptr,  // cancellable
+        getter_Transfers(error)));
+    if (error) {
+      if (error->code == G_DBUS_ERROR_UNKNOWN_METHOD) {
+        // The method "SchemeSupported" not available, seems like we're running
+        // older portal. Be optimistic about supported scheme handler
+        LOG("SchemeSupported method not found, fallback to flatpak handler");
+        RefPtr<nsFlatpakHandlerApp> mozApp = new nsFlatpakHandlerApp();
+        mozApp.forget(aApp);
+        return NS_OK;
+      }
+      g_warning("Failed to call SchemeSupported method: %s\n", error->message);
+      return NS_ERROR_FAILURE;
+    }
+
+    gboolean supported;
+    g_variant_get(result, "(b)", &supported);
+    if (!supported) {
+      LOG("Scheme '%s' is NOT supported.\n",
+          PromiseFlatCString(aURIScheme).get());
+      return NS_ERROR_FAILURE;
+    }
+    LOG("Scheme '%s' is supported.\n", PromiseFlatCString(aURIScheme).get());
     RefPtr<nsFlatpakHandlerApp> mozApp = new nsFlatpakHandlerApp();
     mozApp.forget(aApp);
     return NS_OK;
   }
 
   RefPtr<GAppInfo> app_info = dont_AddRef(g_app_info_get_default_for_uri_scheme(
       PromiseFlatCString(aURIScheme).get()));
   if (!app_info) {