/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// GLib does not support xdg-activation before version 2.76, // so set the environment variable manually. // This only works when launching the proces directly, and does // not work when going through the xdg-desktop-portal. // For activation to work when using the portal, you need to use // GLib 2.76 or newer. if (self->activation_token && glib_check_version(2, 76, 0)) {
g_app_launch_context_setenv(context, "XDG_ACTIVATION_TOKEN",
self->activation_token);
}
// Unset this before launching third-party MIME handlers. Otherwise, if // Thunderbird sets this in its startup script (as it does in Debian and // Fedora), and Firefox does not set this in its startup script (it doesn't in // Debian), then Firefox will think it is part of Thunderbird and try to make // Thunderbird the default browser. See bug 1494436.
g_app_launch_context_unsetenv(context, "MOZ_APP_LAUNCHER");
}
NS_IMETHODIMP
nsFlatpakHandlerApp::SetName(const nsAString& aName) { // We don't implement SetName because flatpak system handler name is fixed return NS_OK;
}
// The TMPDIR where files are downloaded when user choose to open them // needs to be accessible from sandbox and host. The default settings // TMPDIR=/tmp is accessible only to the sandbox. That can be the reason // why the gtk_show_uri fails there. // The workaround is to set TMPDIR environment variable in sandbox to // $XDG_CACHE_HOME/tmp before executing Firefox.
gtk_show_uri(nullptr, spec.get(), GDK_CURRENT_TIME, getter_Transfers(error)); if (error) {
NS_WARNING(
nsPrintfCString("Cannot launch flatpak handler: %s", error->message)
.get()); return NS_ERROR_FAILURE;
} return NS_OK;
}
NS_IMETHODIMP
nsGIOHandlerApp::SetName(const nsAString& aName) { // We don't implement SetName because we're using mGIOMimeApp instance for // obtaining application name return NS_OK;
}
NS_IMETHODIMP
nsGIOMimeApp::SetName(const nsAString& aName) { // We don't implement SetName because we're using mGIOMimeApp instance for // obtaining application name return NS_OK;
}
while (*uri_schemes != nullptr) { // XXX(Bug 1631371) Check if this should use a fallible operation as it // pretended earlier.
array->mStrings.AppendElement(*uri_schemes);
uri_schemes++;
}
array.forget(aSchemes); return NS_OK;
}
NS_IMETHODIMP
nsGIOMimeApp::SetAsDefaultForMimeType(nsACString const& aMimeType) {
GUniquePtr<char> content_type(
g_content_type_from_mime_type(PromiseFlatCString(aMimeType).get())); if (!content_type) return NS_ERROR_FAILURE;
GUniquePtr<GError> error;
g_app_info_set_as_default_for_type(mApp, content_type.get(),
getter_Transfers(error)); if (error) {
g_warning("Cannot set application as default for MIME type (%s): %s",
PromiseFlatCString(aMimeType).get(), error->message); return NS_ERROR_FAILURE;
} return NS_OK;
} /** *Setdefaultapplicationforfileswithgivenextensions *@paramfileExtsstringofspaceseparatedextensions *@returnNS_OKwhenapplicationwassetasdefaultforgivenextensions, *NS_ERROR_FAILUREotherwise
*/
NS_IMETHODIMP
nsGIOMimeApp::SetAsDefaultForFileExtensions(nsACString const& fileExts) {
GUniquePtr<GError> error;
GUniquePtr<char> extensions(g_strdup(PromiseFlatCString(fileExts).get())); char* ext_pos = extensions.get(); char* space_pos;
while ((space_pos = strchr(ext_pos, ' ')) || (*ext_pos != '\0')) { if (space_pos) {
*space_pos = '\0';
}
g_app_info_set_as_default_for_extension(mApp, ext_pos,
getter_Transfers(error)); if (error) {
g_warning("Cannot set application as default for extension (%s): %s",
ext_pos, error->message); return NS_ERROR_FAILURE;
} if (space_pos) {
ext_pos = space_pos + 1;
} else {
*ext_pos = '\0';
}
} return NS_OK;
}
g_app_info_set_as_default_for_type(mApp, contentType.get(),
getter_Transfers(error)); if (error) {
g_warning("Cannot set application as default for URI scheme (%s): %s",
PromiseFlatCString(aURIScheme).get(), error->message); return NS_ERROR_FAILURE;
}
// Its consistent with the way `gio mime x-scheme-handler/contentType // some.desktop` registers mime types to also add the registered application // to the list of supported applications for the handler.
g_app_info_set_as_last_used_for_type(mApp, contentType.get(),
getter_Transfers(error)); if (error) {
g_warning("Cannot register as compatible URI scheme handler for %s: %s",
PromiseFlatCString(aURIScheme).get(), error->message); return NS_ERROR_FAILURE;
}
// Portals works with DBus only. #ifdef MOZ_ENABLE_DBUS // Application in flatpak sandbox does not have access to the list // 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)) {
LOG(" using portal"); if (mozilla::net::IsLoopbackHostname(aURIScheme)) {
LOG(" quit, IsLoopbackHostname"); // 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;
nsAppShell::DBusConnectionCheck();
RefPtr<GDBusProxy> proxy = dont_AddRef(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);
RefPtr<GVariant> 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.",
PromiseFlatCString(aURIScheme).get()); return NS_ERROR_FAILURE;
}
LOG(" Scheme '%s' is supported.", PromiseFlatCString(aURIScheme).get());
RefPtr<nsFlatpakHandlerApp> mozApp = new nsFlatpakHandlerApp();
mozApp.forget(aApp); return NS_OK;
} #endif
RefPtr<GAppInfo> app_info = dont_AddRef(g_app_info_get_default_for_uri_scheme(
PromiseFlatCString(aURIScheme).get())); if (!app_info) {
LOG(" Failed to get info from g_app_info_get_default_for_uri_scheme()"); return NS_ERROR_FAILURE;
}
LOG(" g_app_info_get_default_for_uri_scheme() provides %s : %s",
g_app_info_get_name(app_info), g_app_info_get_executable(app_info));
RefPtr<nsGIOMimeApp> mozApp = new nsGIOMimeApp(app_info.forget());
mozApp.forget(aApp); return NS_OK;
}
NS_IMETHODIMP
nsGIOService::GetAppsForURIScheme(const nsACString& aURIScheme,
nsIMutableArray** aResult) { // We don't need to return the nsFlatpakHandlerApp here because // it would be skipped by the callers anyway. // The preferred handler is provided by GetAppForURIScheme. // This method returns all possible application handlers // including preferred one. The callers skips the preferred // handler in this list to avoid duplicate records in the list // they create.
nsCOMPtr<nsIMutableArray> handlersArray =
do_CreateInstance(NS_ARRAY_CONTRACTID);
GList* appInfoList = g_app_info_get_all_for_type(contentType.get()); // g_app_info_get_all_for_type returns NULL when no appinfo is found // or error occurs (contentType is NULL). We are fine with empty app list // and we're sure that contentType is not NULL, so we won't return failure. if (appInfoList) {
GList* appInfo = appInfoList; while (appInfo) {
nsCOMPtr<nsIGIOMimeApp> mimeApp = new nsGIOMimeApp(dont_AddRef(G_APP_INFO(appInfo->data)));
handlersArray->AppendElement(mimeApp);
LOG(" adding %s : %s", g_app_info_get_name(G_APP_INFO(appInfo->data)),
g_app_info_get_executable(G_APP_INFO(appInfo->data)));
appInfo = appInfo->next;
}
g_list_free(appInfoList);
} else {
LOG(" g_app_info_get_all_for_type() is empty");
}
handlersArray.forget(aResult); return NS_OK;
}
// Flatpak does not reveal installed application to the sandbox, // we need to create generic system handler. if (widget::ShouldUsePortal(widget::PortalKind::MimeHandler)) {
LOG(" using portal");
RefPtr<nsFlatpakHandlerApp> mozApp = new nsFlatpakHandlerApp();
mozApp.forget(aApp); return NS_OK;
}
// GIO returns "unknown" appinfo for the application/octet-stream, which is // useless. It's better to fallback to create appinfo from file extension // later. if (g_content_type_is_unknown(content_type.get())) {
LOG(" g_content_type_from_mime_type() return unknown app."); return NS_ERROR_NOT_AVAILABLE;
}
RefPtr<GAppInfo> app_info =
dont_AddRef(g_app_info_get_default_for_type(content_type.get(), false)); if (!app_info) {
LOG(" g_app_info_get_default_for_type() failed."); return NS_ERROR_FAILURE;
}
LOG(" g_app_info_get_default_for_type() gives us %s : %s",
g_app_info_get_name(app_info), g_app_info_get_executable(app_info)); #ifdef __OpenBSD__ char* t;
t = g_find_program_in_path(g_app_info_get_executable(app_info)); if (t != nullptr) {
g_debug("%s is registered as handler for %s, binary available as %s",
g_app_info_get_executable(app_info), content_type.get(), t);
} else {
g_warning( "%s is registered as handler for %s but not available in PATH " "(missing unveil ?)",
g_app_info_get_executable(app_info), content_type.get());
} #endif
RefPtr<nsGIOMimeApp> mozApp = new nsGIOMimeApp(app_info.forget());
mozApp.forget(aApp); return NS_OK;
}
// Will take ownership of the fd, so we dont have to care about it anymore
RefPtr<GUnixFDList> fd_list =
dont_AddRef(g_unix_fd_list_new_from_array(&fd, 1));
// Try to find relevant and existing GAppInfo in all installed application // We do this by comparing each GAppInfo's executable with out own for (GList* node = apps; node; node = node->next) {
RefPtr<GAppInfo> app_info_from_list = dont_AddRef((GAppInfo*)node->data);
LOG(" checking %s : %s", g_app_info_get_name(app_info_from_list),
g_app_info_get_executable(app_info_from_list));
node->data = nullptr; if (!app_info) { // If the executable is not absolute, get it's full path
GUniquePtr<char> executable(g_find_program_in_path(
g_app_info_get_executable(app_info_from_list)));
if (executable &&
strcmp(executable.get(), PromiseFlatCString(aCmd).get()) == 0) {
app_info = std::move(app_info_from_list);
LOG(" found %s : %s", g_app_info_get_name(app_info),
g_app_info_get_executable(app_info)); // Can't break here because we need to keep iterating to unref the other // nodes.
}
}
}
g_list_free(apps); if (!app_info) {
LOG(" failed to get application");
*aAppInfo = nullptr; return NS_ERROR_NOT_AVAILABLE;
}
RefPtr<nsGIOMimeApp> app = new nsGIOMimeApp(app_info.forget());
app.forget(aAppInfo); return NS_OK;
}
RefPtr<GAppInfo> appInfo =
dont_AddRef((GAppInfo*)g_desktop_app_info_new(aAppId)); if (!appInfo) {
LOG(" Appinfo not found");
g_warning("Appinfo not found for: %s", aAppId); return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIGIOHandlerApp> mozApp = new nsGIOHandlerApp(appInfo.forget());
// Using G_APP_INFO_CREATE_SUPPORTS_URIS calling // g_app_info_create_from_commandline appends %u to the cmd even when cmd // already contains this parameter. To avoid that we're going to remove // arguments before passing to it.
nsAutoCString commandWithoutArgs;
nsresult rv = GetCommandFromCommandline(cmd, commandWithoutArgs);
NS_ENSURE_SUCCESS(rv, rv);
GUniquePtr<GError> error;
RefPtr<GAppInfo> app_info = dont_AddRef(g_app_info_create_from_commandline(
commandWithoutArgs.get(), PromiseFlatCString(appName).get(),
G_APP_INFO_CREATE_SUPPORTS_URIS, getter_Transfers(error))); if (!app_info) {
g_warning("Cannot create application info from command: %s",
error->message); return NS_ERROR_FAILURE;
}
// Check if executable exist in path
GUniquePtr<gchar> executableWithFullPath(
g_find_program_in_path(commandWithoutArgs.get())); if (!executableWithFullPath) {
LOG(" quit, program not found in path"); return NS_ERROR_FILE_NOT_FOUND;
}
RefPtr<nsGIOMimeApp> mozApp = new nsGIOMimeApp(app_info.forget());
mozApp.forget(appInfo); return NS_OK;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.