diff options
Diffstat (limited to 'src/core/content_client_qt.cpp')
-rw-r--r-- | src/core/content_client_qt.cpp | 201 |
1 files changed, 126 insertions, 75 deletions
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp index 6c914b772..b6a0909b0 100644 --- a/src/core/content_client_qt.cpp +++ b/src/core/content_client_qt.cpp @@ -1,50 +1,15 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "content_client_qt.h" #include "base/command_line.h" #include "base/files/file_util.h" +#include "base/json/json_string_value_serializer.h" #include "base/strings/string_piece.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" +#include "base/values.h" #include "base/version.h" #include "content/public/common/cdm_info.h" #include "content/public/common/content_constants.h" @@ -53,6 +18,7 @@ #include "extensions/common/constants.h" #include "media/base/media_switches.h" #include "media/base/video_codecs.h" +#include "media/cdm/supported_audio_codecs.h" #include "media/media_buildflags.h" #include "ui/base/layout.h" #include "ui/base/l10n/l10n_util.h" @@ -64,8 +30,10 @@ #include <QLibraryInfo> #include <QString> + #if BUILDFLAG(ENABLE_LIBRARY_CDMS) #include "media/cdm/cdm_paths.h" // nogncheck +#include "media/cdm/clear_key_cdm_common.h" #include "third_party/widevine/cdm/buildflags.h" #include "third_party/widevine/cdm/widevine_cdm_common.h" #if BUILDFLAG(ENABLE_WIDEVINE) && !BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) @@ -73,9 +41,9 @@ // File name of the CDM on different platforms. const char kWidevineCdmFileName[] = -#if defined(OS_MAC) +#if BUILDFLAG(IS_MAC) "widevinecdm.plugin"; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) "widevinecdm.dll"; #else // OS_LINUX, etc. "libwidevinecdm.so"; @@ -84,9 +52,8 @@ const char kWidevineCdmFileName[] = #endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) #if QT_CONFIG(webengine_printing_and_pdf) +#include "components/pdf/common/internal_plugin_helpers.h" #include "pdf/pdf.h" -#include "pdf/pdf_ppapi.h" -const char kPdfPluginMimeType[] = "application/x-google-chrome-pdf"; const char kPdfPluginPath[] = "internal-pdf-viewer"; #endif // QT_CONFIG(webengine_printing_and_pdf) @@ -96,7 +63,7 @@ static QString webenginePluginsPath() { // Look for plugins in /plugins/webengine or application dir. static bool initialized = false; - static QString potentialPluginsPath = QLibraryInfo::location(QLibraryInfo::PluginsPath) % QLatin1String("/webengine"); + static QString potentialPluginsPath = QLibraryInfo::path(QLibraryInfo::PluginsPath) % QLatin1String("/webengine"); if (!initialized) { initialized = true; if (!QFileInfo::exists(potentialPluginsPath)) @@ -133,14 +100,14 @@ static QString getProgramFilesDir(bool x86Dir = false) // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE.Chromium file. -#include "content/public/common/pepper_plugin_info.h" +#include "content/public/common/content_plugin_info.h" #include "ppapi/shared_impl/ppapi_permissions.h" static QString ppapiPluginsPath() { // Look for plugins in /plugins/ppapi or application dir. static bool initialized = false; - static QString potentialPluginsPath = QLibraryInfo::location(QLibraryInfo::PluginsPath) % QLatin1String("/ppapi"); + static QString potentialPluginsPath = QLibraryInfo::path(QLibraryInfo::PluginsPath) % QLatin1String("/ppapi"); if (!initialized) { initialized = true; if (!QFileInfo::exists(potentialPluginsPath)) @@ -149,28 +116,27 @@ static QString ppapiPluginsPath() return potentialPluginsPath; } -void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) +void ComputeBuiltInPlugins(std::vector<content::ContentPluginInfo> *plugins) { #if QT_CONFIG(webengine_printing_and_pdf) - content::PepperPluginInfo pdf_info; + static constexpr char kPDFPluginExtension[] = "pdf"; + static constexpr char kPDFPluginDescription[] = "Portable Document Format"; + content::ContentPluginInfo pdf_info; pdf_info.is_internal = true; pdf_info.is_out_of_process = true; pdf_info.name = "Chromium PDF Viewer"; - pdf_info.description = "Portable Document Format"; + pdf_info.description = kPDFPluginDescription; pdf_info.path = base::FilePath::FromUTF8Unsafe(kPdfPluginPath); - content::WebPluginMimeType pdf_mime_type(kPdfPluginMimeType, "pdf", "Portable Document Format"); + content::WebPluginMimeType pdf_mime_type( + pdf::kInternalPluginMimeType, kPDFPluginExtension, kPDFPluginDescription); pdf_info.mime_types.push_back(pdf_mime_type); - pdf_info.internal_entry_points.get_interface = chrome_pdf::PPP_GetInterface; - pdf_info.internal_entry_points.initialize_module = chrome_pdf::PPP_InitializeModule; - pdf_info.internal_entry_points.shutdown_module = chrome_pdf::PPP_ShutdownModule; - pdf_info.permissions = ppapi::PERMISSION_DEV | ppapi::PERMISSION_PDF; plugins->push_back(pdf_info); #endif // QT_CONFIG(webengine_printing_and_pdf) } namespace QtWebEngineCore { -void ContentClientQt::AddPepperPlugins(std::vector<content::PepperPluginInfo>* plugins) +void ContentClientQt::AddPlugins(std::vector<content::ContentPluginInfo> *plugins) { ComputeBuiltInPlugins(plugins); } @@ -181,6 +147,40 @@ void ContentClientQt::AddPepperPlugins(std::vector<content::PepperPluginInfo>* p namespace QtWebEngineCore { #if defined(WIDEVINE_CDM_AVAILABLE_NOT_COMPONENT) +#if defined(Q_OS_LINUX) +static const QDir widevineCdmDirHint(const QDir &widevineDir) +{ + const QString hintFilePath = widevineDir.absolutePath() % QDir::separator() + % QLatin1String("latest-component-updated-widevine-cdm"); + if (!QFileInfo::exists(hintFilePath)) { + // CDM hint file does not exist. + return widevineDir; + } + + std::string jsonString; + if (!base::ReadFileToString(toFilePath(hintFilePath), &jsonString)) { + // Could not read the CDM hint file. + return widevineDir; + } + + std::string error_message; + JSONStringValueDeserializer deserializer(jsonString); + std::unique_ptr<base::Value> dict = deserializer.Deserialize(nullptr, &error_message); + if (!dict || !dict->is_dict()) { + DLOG(ERROR) << "Could not deserialize the CDM hint file. Error: " + << error_message; + // Could not deserialize the CDM hint file. + return widevineDir; + } + + std::string *widevineCdmDirPath = dict->GetDict().FindString("Path"); + if (!widevineCdmDirPath) + return widevineDir; + + return QDir(QString::fromStdString(*widevineCdmDirPath)); +} +#endif // defined(Q_OS_LINUX) + static bool IsWidevineAvailable(base::FilePath *cdm_path, media::CdmCapability *capability) { @@ -250,19 +250,61 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path, } } #elif defined(Q_OS_LINUX) - pluginPaths << QStringLiteral("/opt/google/chrome/libwidevinecdm.so") // Old Google Chrome + QList<QDir> potentialWidevineVersionDirs; + + // Google Chrome widevine modules + QDir chromeWidevineDir(QDir::homePath() + "/.config/google-chrome/WidevineCdm"); + if (chromeWidevineDir.exists()) + potentialWidevineVersionDirs << widevineCdmDirHint(chromeWidevineDir); + + // Firefox widevine modules + QDir firefoxPotentialProfilesDir(QDir::homePath() + "/.mozilla/firefox"); + if (firefoxPotentialProfilesDir.exists()) { + QFileInfoList firefoxProfileDirs = firefoxPotentialProfilesDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed); + for (const QFileInfo &info : firefoxProfileDirs) { + QDir widevinePluginsDir(info.absoluteFilePath() + "/gmp-widevinecdm"); + if (widevinePluginsDir.exists()) + potentialWidevineVersionDirs << widevinePluginsDir; + } + } + + // Chromium widevine modules (might not work with proprietary codecs) + QDir chromiumWidevineDir(QDir::homePath() + "/.config/chromium/WidevineCdm"); + if (chromiumWidevineDir.exists()) + potentialWidevineVersionDirs << widevineCdmDirHint(chromiumWidevineDir); + + // Search for widewine versions + for (const QDir &dir : potentialWidevineVersionDirs) { + QFileInfoList widevineVersionDirs = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed); + widevineVersionDirs.prepend(QFileInfo(dir.absolutePath())); + // ### alternatively look up in the manifest.json and take the path from there. #if Q_PROCESSOR_WORDSIZE == 8 - << QStringLiteral("/opt/google/chrome/WidevineCdm/_platform_specific/linux_x64/libwidevinecdm.so") + const QString library = QLatin1String("/_platform_specific/linux_x64/libwidevinecdm.so"); #else - << QStringLiteral("/opt/google/chrome/WidevineCdm/_platform_specific/linux_x86/libwidevinecdm.so") + const QString library = QLatin1String("/_platform_specific/linux_x86/libwidevinecdm.so"); #endif - << QStringLiteral("/usr/lib/chromium/libwidevinecdm.so") // Arch + for (const QFileInfo &info : widevineVersionDirs) { + pluginPaths << info.absoluteFilePath() + "/libwidevinecdm.so"; + pluginPaths << info.absoluteFilePath() + library; + } + } + + // Fixed paths: + pluginPaths << QStringLiteral("/usr/lib/chromium/libwidevinecdm.so") // Arch << QStringLiteral("/usr/lib/chromium-browser/libwidevinecdm.so") // Ubuntu/neon - << QStringLiteral("/usr/lib64/chromium/libwidevinecdm.so"); // OpenSUSE style + << QStringLiteral("/usr/lib64/chromium/libwidevinecdm.so") // OpenSUSE style +#if Q_PROCESSOR_WORDSIZE == 8 + << QStringLiteral("/usr/lib64/chromium-browser/WidevineCdm/_platform_specific/linux_x64/libwidevinecdm.so") // Gentoo + << QStringLiteral("/opt/google/chrome/WidevineCdm/_platform_specific/linux_x64/libwidevinecdm.so") // Old Google Chrome +#else + << QStringLiteral("/usr/lib/chromium-browser/WidevineCdm/_platform_specific/linux_x86/libwidevinecdm.so") // Gentoo + << QStringLiteral("/opt/google/chrome/WidevineCdm/_platform_specific/linux_x86/libwidevinecdm.so") // Old Google Chrome +#endif + << QStringLiteral("/opt/google/chrome/libwidevinecdm.so"); // Older Google Chrome #endif } - for (const QString &pluginPath : qAsConst(pluginPaths)) { + for (const QString &pluginPath : std::as_const(pluginPaths)) { *cdm_path = QtWebEngineCore::toFilePath(pluginPath); if (base::PathExists(*cdm_path)) { // Add the supported codecs as if they came from the component manifest. @@ -277,6 +319,8 @@ static bool IsWidevineAvailable(base::FilePath *cdm_path, #if BUILDFLAG(ENABLE_PLATFORM_HEVC) capability->video_codecs.emplace(media::VideoCodec::kHEVC, kAllProfiles); #endif + capability->audio_codecs = media::GetCdmSupportedAudioCodecs(); + // Add the supported encryption schemes as if they came from the // component manifest. This list must match the CDM that is being // bundled with Chrome. @@ -305,7 +349,7 @@ void ContentClientQt::AddContentDecryptionModules(std::vector<content::CdmInfo> const base::Version version; cdms->push_back(content::CdmInfo(kWidevineKeySystem, Robustness::kSoftwareSecure, std::move(capability), /*supports_sub_key_systems=*/false, kWidevineCdmDisplayName, - kWidevineCdmType, version, cdm_path, kWidevineCdmFileSystemId)); + kWidevineCdmType, version, cdm_path)); } #endif // defined(WIDEVINE_CDM_AVAILABLE_NOT_COMPONENT) @@ -314,35 +358,27 @@ void ContentClientQt::AddContentDecryptionModules(std::vector<content::CdmInfo> base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); base::FilePath clear_key_cdm_path = command_line->GetSwitchValuePath(switches::kClearKeyCdmPathForTesting); if (!clear_key_cdm_path.empty() && base::PathExists(clear_key_cdm_path)) { - // TODO(crbug.com/764480): Remove these after we have a central place for - // External Clear Key (ECK) related information. - // Normal External Clear Key key system. - const char kExternalClearKeyKeySystem[] = "org.chromium.externalclearkey"; - // A variant of ECK key system that has a different GUID. - const char kExternalClearKeyDifferentGuidTestKeySystem[] = - "org.chromium.externalclearkey.differentguid"; - // Supported codecs are hard-coded in ExternalClearKeyProperties. media::CdmCapability capability( {}, {}, {media::EncryptionScheme::kCenc, media::EncryptionScheme::kCbcs}, {media::CdmSessionType::kTemporary, media::CdmSessionType::kPersistentLicense}); - // Register kExternalClearKeyDifferentGuidTestKeySystem first separately. + // Register media::kExternalClearKeyDifferentCdmTypeTestKeySystem first separately. // Otherwise, it'll be treated as a sub-key-system of normal // kExternalClearKeyKeySystem. See MultipleCdmTypes test in // ECKEncryptedMediaTest. - cdms->push_back(content::CdmInfo(kExternalClearKeyDifferentGuidTestKeySystem, + cdms->push_back(content::CdmInfo(media::kExternalClearKeyDifferentCdmTypeTestKeySystem, Robustness::kSoftwareSecure, capability, /*supports_sub_key_systems=*/false, media::kClearKeyCdmDisplayName, media::kClearKeyCdmDifferentCdmType, base::Version("0.1.0.0"), - clear_key_cdm_path, media::kClearKeyCdmFileSystemId)); + clear_key_cdm_path)); - cdms->push_back(content::CdmInfo(kExternalClearKeyKeySystem, + cdms->push_back(content::CdmInfo(media::kExternalClearKeyKeySystem, Robustness::kSoftwareSecure, capability, /*supports_sub_key_systems=*/true, media::kClearKeyCdmDisplayName, media::kClearKeyCdmType, base::Version("0.1.0.0"), - clear_key_cdm_path, media::kClearKeyCdmFileSystemId)); + clear_key_cdm_path)); } #endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) } @@ -381,4 +417,19 @@ std::u16string ContentClientQt::GetLocalizedString(int message_id) return l10n_util::GetStringUTF16(message_id); } +// This method is a copy from chrome/common/chrome_content_client.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.Chromium file. +blink::OriginTrialPolicy *ContentClientQt::GetOriginTrialPolicy() +{ + // Prevent initialization race (see crbug.com/721144). There may be a + // race when the policy is needed for worker startup (which happens on a + // separate worker thread). + base::AutoLock auto_lock(origin_trial_policy_lock_); + if (!origin_trial_policy_) + origin_trial_policy_ = std::make_unique<embedder_support::OriginTrialPolicyImpl>(); + return origin_trial_policy_.get(); +} + } // namespace QtWebEngineCore |