diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-17 14:24:12 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-06-14 09:25:32 +0000 |
commit | de47955be72b2363c5dff2b1f407be993b0f6031 (patch) | |
tree | 640141bb28ee140258453d3dc20e048c75a8fed2 | |
parent | ed85627aba4507280c4f9506dc1ea22b2d033284 (diff) | |
download | qtwebengine-chromium-de47955be72b2363c5dff2b1f407be993b0f6031.tar.gz |
Add service to handle spellchecker
Change-Id: Icd1efe6f0bab3a9cc3c952008f454fe5b872107c
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
9 files changed, 285 insertions, 15 deletions
diff --git a/chromium/chrome/browser/spellchecker/spellcheck_service.cc b/chromium/chrome/browser/spellchecker/spellcheck_service.cc index ef444bd5c6f..bdf723d7000 100644 --- a/chromium/chrome/browser/spellchecker/spellcheck_service.cc +++ b/chromium/chrome/browser/spellchecker/spellcheck_service.cc @@ -13,10 +13,14 @@ #include "base/synchronization/waitable_event.h" #include "base/values.h" #include "build/build_config.h" +#if defined (TOOLKIT_QT) +#include "qtwebengine/browser/service_qt.h" +#else #include "chrome/browser/chrome_service.h" +#include "chrome/common/constants.mojom.h" +#endif #include "chrome/browser/spellchecker/spellcheck_factory.h" #include "chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h" -#include "chrome/common/constants.mojom.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_member.h" #include "components/prefs/pref_service.h" @@ -204,11 +208,19 @@ void SpellcheckService::InitForRenderer( } spellcheck::mojom::SpellCheckerPtr spellchecker; +#if defined (TOOLKIT_QT) + ServiceQt::GetInstance()->connector()->BindInterface( + service_manager::Identity("qtwebengine_renderer", + renderer_identity.user_id(), + renderer_identity.instance()), + &spellchecker); +#else ChromeService::GetInstance()->connector()->BindInterface( service_manager::Identity(chrome::mojom::kRendererServiceName, renderer_identity.user_id(), renderer_identity.instance()), &spellchecker); +#endif spellchecker->Initialize(std::move(dictionaries), custom_words, enable); } @@ -288,14 +300,22 @@ void SpellcheckService::OnCustomDictionaryChanged( const std::vector<std::string> deletions(change.to_remove().begin(), change.to_remove().end()); while (!process_hosts.IsAtEnd()) { - service_manager::Identity renderer_identity = - process_hosts.GetCurrentValue()->GetChildIdentity(); + service_manager::Identity renderer_identity = + process_hosts.GetCurrentValue()->GetChildIdentity(); spellcheck::mojom::SpellCheckerPtr spellchecker; +#if defined (TOOLKIT_QT) + ServiceQt::GetInstance()->connector()->BindInterface( + service_manager::Identity("qtwebengine_renderer", + renderer_identity.user_id(), + renderer_identity.instance()), + &spellchecker); +#else ChromeService::GetInstance()->connector()->BindInterface( service_manager::Identity(chrome::mojom::kRendererServiceName, renderer_identity.user_id(), renderer_identity.instance()), &spellchecker); +#endif spellchecker->CustomDictionaryChanged(additions, deletions); process_hosts.Advance(); } diff --git a/chromium/components/spellcheck/common/spellcheck_common.cc b/chromium/components/spellcheck/common/spellcheck_common.cc index 0c676161b28..dd266d165b1 100644 --- a/chromium/components/spellcheck/common/spellcheck_common.cc +++ b/chromium/components/spellcheck/common/spellcheck_common.cc @@ -137,7 +137,7 @@ base::FilePath GetVersionedFileName(base::StringPiece input_language, } std::string versioned_bdict_file_name(language + version + ".bdic"); #else - std::string versioned_bdict_file_name(input_language + ".bdic"); + std::string versioned_bdict_file_name(std::string(input_language) + ".bdic"); #endif return dict_dir.AppendASCII(versioned_bdict_file_name); } diff --git a/chromium/qtwebengine/browser/BUILD.gn b/chromium/qtwebengine/browser/BUILD.gn index 122e55b089a..686252afabf 100644 --- a/chromium/qtwebengine/browser/BUILD.gn +++ b/chromium/qtwebengine/browser/BUILD.gn @@ -18,6 +18,10 @@ service_manifest("qtwebengine_manifest") { source = "//qtwebengine/browser/qtwebengine_manifest.json" } +service_manifest("qtwebengine_renderer_manifest") { + source = "//qtwebengine/browser/qtwebengine_renderer_manifest.json" +} + service_manifest("qtwebengine_content_renderer_manifest_overlay") { source = "//qtwebengine/browser/qtwebengine_content_renderer_manifest_overlay.json" } @@ -55,6 +59,7 @@ group("service_manifests") { qtwebengine_embedded_services = [ ":qtwebengine_content_renderer_manifest", + ":qtwebengine_renderer_manifest", ] catalog("catalog") { diff --git a/chromium/qtwebengine/browser/qt_webengine_resources.grd b/chromium/qtwebengine/browser/qt_webengine_resources.grd index 6a264e9eeec..cab935837b2 100644 --- a/chromium/qtwebengine/browser/qt_webengine_resources.grd +++ b/chromium/qtwebengine/browser/qt_webengine_resources.grd @@ -18,6 +18,7 @@ <include name="IDR_SANDBOX_INTERNALS_HTML" file="../../chrome/browser/resources/sandbox_internals/sandbox_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" /> <include name="IDR_SANDBOX_INTERNALS_JS" file="../../chrome/browser/resources/sandbox_internals/sandbox_internals.js" type="BINDATA" compress="gzip" /> </if> + <include name="IDR_QTWEBENGINE_RENDERER_SERVICE_MANIFEST" file="qtwebengine_renderer_manifest.json" type="BINDATA" /> <include name="IDR_QTWEBENGINE_CONTENT_RENDERER_MANIFEST_OVERLAY" file="gen\qtwebengine\browser\qtwebengine_content_renderer_manifest_overlay.json" use_base_dir="false" type="BINDATA" /> <include name="IDR_QTWEBENGINE_CONTENT_PACKAGED_SERVICES_MANIFEST_OVERLAY" use_base_dir="false" file="gen\qtwebengine\browser\qtwebengine_content_packaged_services_manifest_overlay.json" type="BINDATA" /> </includes> diff --git a/chromium/qtwebengine/browser/qtwebengine_content_renderer_manifest_overlay.json b/chromium/qtwebengine/browser/qtwebengine_content_renderer_manifest_overlay.json index 1659d0be99f..52dc97959f3 100644 --- a/chromium/qtwebengine/browser/qtwebengine_content_renderer_manifest_overlay.json +++ b/chromium/qtwebengine/browser/qtwebengine_content_renderer_manifest_overlay.json @@ -1,16 +1,6 @@ { "display_name": "QtWebEngine Render Process", "interface_provider_specs": { - "service_manager:connector": { - "provides": { - "browser": [ - "spellcheck::mojom::SpellChecker" - ] - }, - "requires": { - "qtwebengine": [ "renderer" ] - } - }, "navigation:frame": { "provides": { "browser": [ diff --git a/chromium/qtwebengine/browser/qtwebengine_manifest.json b/chromium/qtwebengine/browser/qtwebengine_manifest.json index 64ab7c01ba6..fe1b060ca80 100644 --- a/chromium/qtwebengine/browser/qtwebengine_manifest.json +++ b/chromium/qtwebengine/browser/qtwebengine_manifest.json @@ -9,8 +9,11 @@ ] }, "requires": { + "qtwebengine_renderer": [ "browser" ], "service_manager": [ - "service_manager:all_users" + "service_manager:all_users", + "service_manager:client_process", + "service_manager:instance_name" ] } } diff --git a/chromium/qtwebengine/browser/qtwebengine_renderer_manifest.json b/chromium/qtwebengine/browser/qtwebengine_renderer_manifest.json new file mode 100644 index 00000000000..b2458333d83 --- /dev/null +++ b/chromium/qtwebengine/browser/qtwebengine_renderer_manifest.json @@ -0,0 +1,16 @@ +{ + "name": "qtwebengine_renderer", + "display_name": "QtWebEngine Renderer", + "interface_provider_specs": { + "service_manager:connector": { + "provides": { + "browser": [ + "spellcheck::mojom::SpellChecker" + ] + }, + "requires": { + "qtwebengine": [ "renderer" ] + } + } + } +} diff --git a/chromium/qtwebengine/browser/service_qt.cc b/chromium/qtwebengine/browser/service_qt.cc new file mode 100644 index 00000000000..30ed269e8dd --- /dev/null +++ b/chromium/qtwebengine/browser/service_qt.cc @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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$ +** +****************************************************************************/ + +// based on chrome/browser/chrome_service.cc: +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "service_qt.h" + +#include "base/no_destructor.h" +#include "components/spellcheck/spellcheck_buildflags.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/content_browser_client.h" +#include "services/service_manager/public/cpp/binder_registry.h" +#include "services/service_manager/public/cpp/connector.h" +#include "services/service_manager/public/cpp/service.h" +#include "services/service_manager/public/cpp/service_context.h" + +#if BUILDFLAG(ENABLE_SPELLCHECK) +#include "chrome/browser/spellchecker/spell_check_host_chrome_impl.h" +#endif + +class ServiceQt::IOThreadContext : public service_manager::Service { +public: + IOThreadContext(); + ~IOThreadContext() override = default; + + void BindConnector(service_manager::mojom::ConnectorRequest connector_request); + +private: + void BindConnectorOnIOThread(service_manager::mojom::ConnectorRequest connector_request); + + // service_manager::Service: + void OnStart() override; + void OnBindInterface(const service_manager::BindSourceInfo &remote_info, + const std::string &name, + mojo::ScopedMessagePipeHandle handle) override; + + service_manager::mojom::ConnectorRequest m_connectorRequest; + service_manager::BinderRegistry m_registry; + service_manager::BinderRegistryWithArgs<const service_manager::BindSourceInfo&> m_registry_with_source_info; + + DISALLOW_COPY_AND_ASSIGN(IOThreadContext); +}; + +ServiceQt::IOThreadContext::IOThreadContext() +{ + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner = + content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI); +#if BUILDFLAG(ENABLE_SPELLCHECK) + m_registry_with_source_info.AddInterface(base::Bind(&SpellCheckHostChromeImpl::Create), ui_task_runner); +#endif +} + +void ServiceQt::IOThreadContext::BindConnector(service_manager::mojom::ConnectorRequest connector_request) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + // NOTE: It's not safe to modify |connector_request_| here since it's read + // on the IO thread. Post a task instead. As long as this task is posted + // before any code attempts to connect to the chrome service, there's no + // race. + content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::IO)->PostTask( + FROM_HERE, + base::BindOnce(&IOThreadContext::BindConnectorOnIOThread, + base::Unretained(this), + std::move(connector_request))); +} + +void ServiceQt::IOThreadContext::BindConnectorOnIOThread(service_manager::mojom::ConnectorRequest connector_request) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + m_connectorRequest = std::move(connector_request); +} + +void ServiceQt::IOThreadContext::OnStart() +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + DCHECK(m_connectorRequest.is_pending()); + context()->connector()->BindConnectorRequest(std::move(m_connectorRequest)); +} + +void ServiceQt::IOThreadContext::OnBindInterface(const service_manager::BindSourceInfo &remote_info, + const std::string &name, + mojo::ScopedMessagePipeHandle handle) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + content::OverrideOnBindInterface(remote_info, name, &handle); + if (!handle.is_valid()) + return; + + if (!m_registry.TryBindInterface(name, &handle)) + m_registry_with_source_info.TryBindInterface(name, &handle, remote_info); +} + +ServiceQt *ServiceQt::GetInstance() +{ + static base::NoDestructor<ServiceQt> service; + return service.get(); +} + +service_manager::EmbeddedServiceInfo::ServiceFactory ServiceQt::CreateServiceQtFactory() +{ + return base::BindRepeating(&ServiceQt::CreateServiceQtWrapper, base::Unretained(this)); +} + +ServiceQt::ServiceQt() : m_ioThreadContext(std::make_unique<IOThreadContext>()) +{} + +ServiceQt::~ServiceQt() = default; + +void ServiceQt::InitConnector() +{ + service_manager::mojom::ConnectorRequest request; + m_connector = service_manager::Connector::Create(&request); + m_ioThreadContext->BindConnector(std::move(request)); +} + +std::unique_ptr<service_manager::Service> ServiceQt::CreateServiceQtWrapper() +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + return std::make_unique<service_manager::ForwardingService>(m_ioThreadContext.get()); +} diff --git a/chromium/qtwebengine/browser/service_qt.h b/chromium/qtwebengine/browser/service_qt.h new file mode 100644 index 00000000000..4aa0a399664 --- /dev/null +++ b/chromium/qtwebengine/browser/service_qt.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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$ +** +****************************************************************************/ + +#ifndef SERVICE_QT_H +#define SERVICE_QT_H + +#include "base/no_destructor.h" +#include "services/service_manager/embedder/embedded_service_info.h" + +namespace service_manager { +class Connector; +class Service; +} // namespace service_manager + +class ServiceQt { +public: + static ServiceQt *GetInstance(); + + void InitConnector(); + service_manager::EmbeddedServiceInfo::ServiceFactory CreateServiceQtFactory(); + service_manager::Connector *connector() { return m_connector.get(); } + +private: + friend class base::NoDestructor<ServiceQt>; + class IOThreadContext; + + ServiceQt(); + ~ServiceQt(); + + std::unique_ptr<service_manager::Service> CreateServiceQtWrapper(); + + const std::unique_ptr<IOThreadContext> m_ioThreadContext; + + std::unique_ptr<service_manager::Connector> m_connector; + + DISALLOW_COPY_AND_ASSIGN(ServiceQt); +}; + +#endif // SERVICE_QT_H |