1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qqmldebugpluginmanager_p.h"
41#include "qqmldebugconnector_p.h"
42#include "qqmldebugservicefactory_p.h"
43#include <QtCore/QPluginLoader>
44#include <QtCore/QCoreApplication>
45#include <QtCore/QDir>
46#include <QtCore/QDebug>
47#include <QtCore/QJsonArray>
48#include <QtCore/QDataStream>
49
50#include <private/qcoreapplication_p.h>
51#include <private/qqmlengine_p.h>
52
53QT_BEGIN_NAMESPACE
54
55// Connectors. We could add more plugins here, and distinguish by arguments to instance()
56Q_QML_DEBUG_PLUGIN_LOADER(QQmlDebugConnector)
57
58// Services
59Q_QML_DEBUG_PLUGIN_LOADER(QQmlDebugService)
60
61int QQmlDebugConnector::s_dataStreamVersion = QDataStream::Qt_4_7;
62
63struct QQmlDebugConnectorParams {
64 QString pluginKey;
65 QStringList services;
66 QString arguments;
67 QQmlDebugConnector *instance;
68
69 QQmlDebugConnectorParams() : instance(nullptr)
70 {
71 if (qApp) {
72 QCoreApplicationPrivate *appD =
73 static_cast<QCoreApplicationPrivate*>(QObjectPrivate::get(qApp));
74 if (appD)
75 arguments = appD->qmljsDebugArgumentsString();
76 }
77 }
78};
79
80Q_GLOBAL_STATIC(QQmlDebugConnectorParams, qmlDebugConnectorParams)
81
82void QQmlDebugConnector::setPluginKey(const QString &key)
83{
84 QQmlDebugConnectorParams *params = qmlDebugConnectorParams();
85 if (params && params->pluginKey != key) {
86 if (params->instance)
87 qWarning() << "QML debugger: Cannot set plugin key after loading the plugin.";
88 else
89 params->pluginKey = key;
90 }
91}
92
93void QQmlDebugConnector::setServices(const QStringList &services)
94{
95 QQmlDebugConnectorParams *params = qmlDebugConnectorParams();
96 if (params)
97 params->services = services;
98}
99
100QString QQmlDebugConnector::commandLineArguments()
101{
102 QQmlDebugConnectorParams *params = qmlDebugConnectorParams();
103 if (!params)
104 return QString();
105 return params->arguments;
106}
107
108QQmlDebugConnector *QQmlDebugConnector::instance()
109{
110 QQmlDebugConnectorParams *params = qmlDebugConnectorParams();
111 if (!params)
112 return nullptr;
113
114 if (!QQmlEnginePrivate::qml_debugging_enabled) {
115 if (!params->arguments.isEmpty()) {
116 qWarning().noquote() << QString::fromLatin1(
117 str: "QML Debugger: Ignoring \"-qmljsdebugger=%1\". Debugging "
118 "has not been enabled.").arg(a: params->arguments);
119 params->arguments.clear();
120 }
121 return nullptr;
122 }
123
124 if (!params->instance) {
125 if (!params->pluginKey.isEmpty()) {
126 params->instance = loadQQmlDebugConnector(key: params->pluginKey);
127 } else if (params->arguments.isEmpty()) {
128 return nullptr; // no explicit class name given and no command line arguments
129 } else if (params->arguments.startsWith(s: QLatin1String("connector:"))) {
130 static const int connectorBegin = int(strlen(s: "connector:"));
131
132 int connectorEnd = params->arguments.indexOf(c: QLatin1Char(','), from: connectorBegin);
133 if (connectorEnd == -1)
134 connectorEnd = params->arguments.length();
135
136 params->instance = loadQQmlDebugConnector(key: params->arguments.mid(
137 position: connectorBegin,
138 n: connectorEnd - connectorBegin));
139 } else {
140 params->instance = loadQQmlDebugConnector(
141 key: params->arguments.startsWith(s: QLatin1String("native")) ?
142 QStringLiteral("QQmlNativeDebugConnector") :
143 QStringLiteral("QQmlDebugServer"));
144 }
145
146 if (params->instance) {
147 const auto metaData = metaDataForQQmlDebugService();
148 for (const QJsonObject &object : metaData) {
149 const auto keys = object.value(key: QLatin1String("MetaData")).toObject()
150 .value(key: QLatin1String("Keys")).toArray();
151 for (const QJsonValue &key : keys) {
152 QString keyString = key.toString();
153 if (params->services.isEmpty() || params->services.contains(str: keyString))
154 loadQQmlDebugService(key: keyString);
155 }
156 }
157 }
158 }
159
160 return params->instance;
161}
162
163QQmlDebugConnectorFactory::~QQmlDebugConnectorFactory()
164{
165 // This is triggered when the plugin is unloaded.
166 QQmlDebugConnectorParams *params = qmlDebugConnectorParams();
167 if (params) {
168 params->pluginKey.clear();
169 params->arguments.clear();
170 params->services.clear();
171 delete params->instance;
172 params->instance = nullptr;
173 }
174}
175
176QT_END_NAMESPACE
177
178#include "moc_qqmldebugconnector_p.cpp"
179

source code of qtdeclarative/src/qml/debugger/qqmldebugconnector.cpp