chromium/chrome/browser/shell_integration_linux.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "chrome/browser/shell_integration_linux.h"

#include <fcntl.h>
#include <stddef.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <memory>
#include <optional>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include "base/base_paths.h"
#include "base/command_line.h"
#include "base/environment.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/safe_base_name.h"
#include "base/i18n/file_util_icu.h"
#include "base/logging.h"
#include "base/memory/ref_counted_memory.h"
#include "base/nix/xdg_util.h"
#include "base/path_service.h"
#include "base/posix/eintr_wrapper.h"
#include "base/process/kill.h"
#include "base/process/launch.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/web_applications/os_integration/web_app_shortcut.h"
#include "chrome/browser/web_applications/web_app_helpers.h"
#include "chrome/common/buildflags.h"
#include "chrome/common/channel_info.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/grit/branded_strings.h"
#include "chrome/grit/chrome_unscaled_resources.h"
#include "components/version_info/version_info.h"
#include "third_party/libxml/chromium/xml_writer.h"
#include "third_party/re2/src/re2/re2.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image_family.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/ozone/public/platform_utils.h"
#include "url/gurl.h"

#if defined(USE_GLIB)
#include <glib.h>
#endif

namespace shell_integration_linux {

const char kXdgSettings[] =;
const char kXdgSettingsDefaultBrowser[] =;
const char kXdgSettingsDefaultSchemeHandler[] =;

// Utility function to get the path to the version of a script shipped with
// Chrome. |script| gives the name of the script. |chrome_version| returns the
// path to the Chrome version of the script, and the return value of the
// function is true if the function is successful and the Chrome version is
// not the script found on the PATH.
bool GetChromeVersionOfScript(const std::string& script,
                              std::string* chrome_version) {}

// Value returned by xdg-settings if it can't understand our request.
const int EXIT_XDG_SETTINGS_SYNTAX_ERROR =;

// We delegate the difficulty of setting the default browser and default url
// scheme handler in Linux desktop environments to an xdg utility, xdg-settings.

// When calling this script we first try to use the script on PATH. If that
// fails we then try to use the script that we have included. This gives
// scripts on the system priority over ours, as distribution vendors may have
// tweaked the script, but still allows our copy to be used if the script on the
// system fails, as the system copy may be missing capabilities of the Chrome
// copy.

// If |scheme| is empty this function sets Chrome as the default browser,
// otherwise it sets Chrome as the default handler application for |scheme|.
bool SetDefaultWebClient(const std::string& scheme) {}

// If |scheme| is empty this function checks if Chrome is the default browser,
// otherwise it checks if Chrome is the default handler application for
// |scheme|.
shell_integration::DefaultWebClientState GetIsDefaultWebClient(
    const std::string& scheme) {}

// https://wiki.gnome.org/Projects/GnomeShell/ApplicationBased
// The WM_CLASS property should be set to the same as the *.desktop file without
// the .desktop extension.  We cannot simply use argv[0] in this case, because
// on the stable channel, the executable name is google-chrome-stable, but the
// desktop file is google-chrome.desktop.
std::string GetDesktopBaseName(const std::string& desktop_file_name) {}

namespace {

#if defined(USE_GLIB)
// Quote a string such that it appears as one verbatim argument for the Exec
// key in a desktop file.
std::string QuoteArgForDesktopFileExec(const std::string& arg) {}

// Quote a command line so it is suitable for use as the Exec key in a desktop
// file. Note: This should be used instead of GetCommandLineString, which does
// not properly quote the string; this function is designed for the Exec key.
std::string QuoteCommandLineForDesktopFileExec(
    const base::CommandLine& command_line) {}
#endif

#if defined(USE_GLIB)
const char kDesktopEntry[] =;
const char kXdgOpenShebang[] =;

void SetActionsForDesktopApplication(
    const base::CommandLine& command_line,
    GKeyFile* key_file,
    std::set<web_app::DesktopActionInfo> action_info) {}
#endif

base::FilePath GetDesktopFileForDefaultSchemeHandler(base::Environment* env,
                                                     const GURL& url) {}

std::string GetDesktopEntryStringValueFromFromDesktopFile(
    const std::string& key,
    const std::string& shortcut_contents) {}

}  // namespace

// Allows LaunchXdgUtility to join a process.
// thread_restrictions.h assumes it to be in shell_integration_linux namespace.
class [[maybe_unused, nodiscard]] LaunchXdgUtilityScopedAllowBaseSyncPrimitives
    : public base::ScopedAllowBaseSyncPrimitives{};

bool LaunchXdgUtility(const std::vector<std::string>& argv, int* exit_code) {}

std::string GetWMClassFromAppName(std::string app_name) {}

std::string GetXdgAppIdForWebApp(std::string app_name,
                                 const base::FilePath& profile_path) {}

namespace internal {

std::string GetDesktopEntryStringValueFromFromDesktopFileForTest(
    const std::string& key,
    const std::string& shortcut_contents) {}

// Get the value of NoDisplay from the [Desktop Entry] section of a .desktop
// file, given in |shortcut_contents|. If the key is not found, returns false.
bool GetNoDisplayFromDesktopFile(const std::string& shortcut_contents) {}

// Gets the path to the Chrome executable or wrapper script.
// Returns an empty path if the executable path could not be found, which should
// never happen.
base::FilePath GetChromeExePath() {}

std::string GetProgramClassName(const base::CommandLine& command_line,
                                const std::string& desktop_file_name) {}

std::string GetProgramClassClass(const base::CommandLine& command_line,
                                 const std::string& desktop_file_name) {}

}  // namespace internal

std::string GetProgramClassName() {}

std::string GetProgramClassClass() {}

std::string GetIconName() {}

bool GetExistingShortcutContents(base::Environment* env,
                                 const base::FilePath& desktop_filename,
                                 std::string* output) {}

std::optional<base::SafeBaseName> GetUniqueWebShortcutFilename(
    const std::string& name) {}

std::vector<base::FilePath> GetExistingProfileShortcutFilenames(
    const base::FilePath& profile_path,
    const base::FilePath& directory) {}

std::string GetDesktopFileContents(
    const base::FilePath& chrome_exe_path,
    const std::string& app_name,
    const GURL& url,
    const std::string& extension_id,
    const std::u16string& title,
    const std::string& icon_name,
    const base::FilePath& profile_path,
    const std::string& categories,
    const std::string& mime_type,
    bool no_display,
    const std::string& run_on_os_login_mode,
    std::set<web_app::DesktopActionInfo> action_info) {}

std::string GetDesktopFileContentsForCommand(
    const base::CommandLine& command_line,
    const std::string& app_name,
    const GURL& url,
    const std::u16string& title,
    const std::string& icon_name,
    const std::string& categories,
    const std::string& mime_type,
    bool no_display,
    std::set<web_app::DesktopActionInfo> action_info) {}

std::string GetDesktopFileContentsForUrlShortcut(
    const std::string& title,
    const GURL& url,
    const base::FilePath& icon_path,
    const base::FilePath& profile_path) {}

std::string GetDirectoryFileContents(const std::u16string& title,
                                     const std::string& icon_name) {}

base::FilePath GetMimeTypesRegistrationFilename(
    const base::FilePath& profile_path,
    const webapps::AppId& app_id) {}

std::string GetMimeTypesRegistrationFileContents(
    const apps::FileHandlers& file_handlers) {}

}  // namespace shell_integration_linux

namespace shell_integration {

bool SetAsDefaultBrowser() {}

bool SetAsDefaultClientForScheme(const std::string& scheme) {}

std::u16string GetApplicationNameForScheme(const GURL& url) {}

DefaultWebClientState GetDefaultBrowser() {}

bool IsFirefoxDefaultBrowser() {}

DefaultWebClientState IsDefaultClientForScheme(const std::string& scheme) {}

namespace internal {

DefaultWebClientSetPermission GetPlatformSpecificDefaultWebClientSetPermission(
    WebClientSetMethod method) {}

}  // namespace internal

}  // namespace shell_integration