OSDN Git Service

Maemo: Support new "mad info" schema.
authorChristian Kandeler <christian.kandeler@nokia.com>
Tue, 30 Nov 2010 12:45:15 +0000 (13:45 +0100)
committerChristian Kandeler <christian.kandeler@nokia.com>
Tue, 30 Nov 2010 12:45:33 +0000 (13:45 +0100)
Reviewed-by: kh1
src/plugins/qt4projectmanager/qt-maemo/maemoqemumanager.cpp
src/plugins/qt4projectmanager/qt-maemo/maemoqemumanager.h

index cee546f..dffe4bc 100644 (file)
@@ -157,14 +157,10 @@ void MaemoQemuManager::qtVersionsChanged(const QList<int> &uniqueIds)
         if (manager->isValidId(uniqueId)) {
             QtVersion *version = manager->version(uniqueId);
             if (version->supportsTargetId(Constants::MAEMO_DEVICE_TARGET_ID)) {
-                const QString &qmake = version->qmakeCommand();
-                const QString &runtimeRoot = runtimeForQtVersion(qmake);
-                if (!runtimeRoot.isEmpty()) {
-                    Runtime runtime(runtimeRoot);
-                    if (QFile::exists(runtimeRoot))
-                        fillRuntimeInformation(&runtime);
+                Runtime runtime = createRuntime(version);
+                if (runtime.isValid()) {
                     runtime.m_watchPath =
-                        runtimeRoot.left(runtimeRoot.lastIndexOf(QLatin1Char('/')));
+                        runtime.m_root.left(runtime.m_root.lastIndexOf(QLatin1Char('/')));
                     m_runtimes.insert(uniqueId, runtime);
                     if (!m_runtimeRootWatcher->directories().contains(runtime.m_watchPath))
                         m_runtimeRootWatcher->addPath(runtime.m_watchPath);
@@ -609,7 +605,7 @@ QString MaemoQemuManager::targetRoot(const QString &qmake) const
     return target.mid(target.lastIndexOf(QLatin1Char('/')) + 1);
 }
 
-bool MaemoQemuManager::fillRuntimeInformation(Runtime *runtime) const
+bool MaemoQemuManager::fillRuntimeInformationForOldMadInfo(Runtime *runtime) const
 {
     const QStringList files = QDir(runtime->m_root).entryList(QDir::Files
         | QDir::NoSymLinks | QDir::NoDotAndDotDot);
@@ -676,31 +672,79 @@ void MaemoQemuManager::setEnvironment(Runtime *runTime,
     }
 }
 
-QString MaemoQemuManager::runtimeForQtVersion(const QString &qmakeCommand) const
+Runtime MaemoQemuManager::createRuntime(const QtVersion *qtVersion) const
 {
-    const QString &target = targetRoot(qmakeCommand);
-    const QString &madRoot = maddeRoot(qmakeCommand);
-
-    const QString madCommand = madRoot + QLatin1String("/bin/mad");
+    Runtime runtime;
+    const QString maddeRootPath = maddeRoot(qtVersion->qmakeCommand());
+    const QString madCommand = maddeRootPath + QLatin1String("/bin/mad");
     if (!QFileInfo(madCommand).exists())
-        return QString();
-
+        return runtime;
     QProcess madProc;
-    const QStringList arguments(QLatin1String("info"));
-
-    MaemoGlobal::callMaddeShellScript(madProc, madRoot, madCommand, arguments);
+    MaemoGlobal::callMaddeShellScript(madProc, maddeRootPath, madCommand,
+        QStringList() << QLatin1String("info"));
     if (!madProc.waitForStarted() || !madProc.waitForFinished())
-        return QString();
+        return runtime;
+    const QByteArray &madInfoOutput = madProc.readAllStandardOutput();
+    const QString &targetName = targetRoot(qtVersion->qmakeCommand());
+    runtime = parseRuntimeFromMadInfo(madInfoOutput, targetName);
+    if (!runtime.m_name.isEmpty()) {
+        runtime.m_root = maddeRootPath + QLatin1String("/runtimes/")
+            + runtime.m_name;
+
+        // TODO: Workaround for missing ssh tag. Fix once MADDE is ready.
+        runtime.m_sshPort = QLatin1String("6666");
+
+        return runtime;
+    } else {
+        return parseRuntimeFromOldMadInfo(madInfoOutput, maddeRootPath, targetName);
+    }
+}
+
+Runtime MaemoQemuManager::parseRuntimeFromMadInfo(const QByteArray &output,
+    const QString &targetName) const
+{
+    QXmlStreamReader infoReader(output);
+    QString runtimeName;
+    QList<Runtime> runtimes;
+    while (infoReader.readNextStartElement()) {
+        if (infoReader.name() == QLatin1String("madde")) {
+            while (infoReader.readNextStartElement()) {
+                if (infoReader.name() == QLatin1String("targets")) {
+                    while (infoReader.readNextStartElement())
+                        handleMadInfoTargetTag(infoReader, runtimeName, targetName);
+                } else if (infoReader.name() == QLatin1String("runtimes")) {
+                    while (infoReader.readNextStartElement()) {
+                        const Runtime &rt = handleMadInfoRuntimeTag(infoReader);
+                        if (!rt.m_name.isEmpty() && !rt.m_bin.isEmpty()
+                                && !rt.m_args.isEmpty()) {
+                            runtimes << rt;
+                        }
+                    }
+                } else {
+                    infoReader.skipCurrentElement();
+                }
+            }
+        }
+    }
+    foreach (const Runtime &rt, runtimes) {
+        if (rt.m_name == runtimeName)
+            return rt;
+    }
+    return Runtime();
+}
 
+Runtime MaemoQemuManager::parseRuntimeFromOldMadInfo(const QString &output,
+    const QString &maddeRootPath, const QString &targetName) const
+{
+    QXmlStreamReader infoReader(output);
     QStringList installedRuntimes;
     QString targetRuntime;
-    QXmlStreamReader infoReader(madProc.readAllStandardOutput());
     while (!infoReader.atEnd() && !installedRuntimes.contains(targetRuntime)) {
         if (infoReader.readNext() == QXmlStreamReader::StartElement) {
             if (targetRuntime.isEmpty()
                 && infoReader.name() == QLatin1String("target")) {
                 const QXmlStreamAttributes &attrs = infoReader.attributes();
-                if (attrs.value(QLatin1String("target_id")) == target)
+                if (attrs.value(QLatin1String("target_id")) == targetName)
                     targetRuntime = attrs.value("runtime_id").toString();
             } else if (infoReader.name() == QLatin1String("runtime")) {
                 const QXmlStreamAttributes attrs = infoReader.attributes();
@@ -725,9 +769,117 @@ QString MaemoQemuManager::runtimeForQtVersion(const QString &qmakeCommand) const
             }
         }
     }
-    if (installedRuntimes.contains(targetRuntime))
-        return madRoot + QLatin1String("/runtimes/") + targetRuntime;
-    return QString();
+
+    Runtime runtime;
+    if (installedRuntimes.contains(targetRuntime)) {
+        runtime.m_name = targetRuntime;
+        runtime.m_root = maddeRootPath + QLatin1String("/runtimes/")
+            + targetRuntime;
+        fillRuntimeInformationForOldMadInfo(&runtime);
+    }
+    return runtime;
+}
+
+
+void MaemoQemuManager::handleMadInfoTargetTag(QXmlStreamReader &infoReader,
+    QString &runtimeName, const QString &targetName) const
+{
+    const QXmlStreamAttributes &attrs = infoReader.attributes();
+    if (infoReader.name() == QLatin1String("target") && runtimeName.isEmpty()
+            && attrs.value(QLatin1String("name")) == targetName
+            && attrs.value(QLatin1String("installed")) == QLatin1String("true")) {
+        while (infoReader.readNextStartElement()) {
+            if (infoReader.name() == QLatin1String("runtime"))
+                runtimeName = infoReader.readElementText();
+            else
+                infoReader.skipCurrentElement();
+        }
+    } else {
+        infoReader.skipCurrentElement();
+    }
+}
+
+Runtime MaemoQemuManager::handleMadInfoRuntimeTag(QXmlStreamReader &infoReader) const
+{
+    Runtime runtime;
+    const QXmlStreamAttributes &attrs = infoReader.attributes();
+    if (infoReader.name() != QLatin1String("runtime")
+            || attrs.value(QLatin1String("installed")) != QLatin1String("true")) {
+        infoReader.skipCurrentElement();
+        return runtime;
+    }
+    runtime.m_name = attrs.value(QLatin1String("name")).toString();
+    while (infoReader.readNextStartElement()) {
+        if (infoReader.name() == QLatin1String("exec-path")) {
+            runtime.m_bin = infoReader.readElementText();
+        } else if (infoReader.name() == QLatin1String("args")) {
+            runtime.m_args = infoReader.readElementText();
+        } else if (infoReader.name() == QLatin1String("environment")) {
+            runtime.m_environment = handleMadInfoEnvironmentTag(infoReader);
+        } else if (infoReader.name() == QLatin1String("tcpportmap")) {
+            runtime.m_freePorts = handleMadInfoTcpPortListTag(infoReader);
+        } else {
+            infoReader.skipCurrentElement();
+        }
+    }
+    return runtime;
+}
+
+QHash<QString, QString> MaemoQemuManager::handleMadInfoEnvironmentTag(QXmlStreamReader &infoReader) const
+{
+    QHash<QString, QString> env;
+    while (infoReader.readNextStartElement()) {
+        const QPair<QString, QString> &var
+            = handleMadInfoVariableTag(infoReader);
+        if (!var.first.isEmpty())
+            env.insert(var.first, var.second);
+    }
+    return env;
+}
+
+QPair<QString, QString> MaemoQemuManager::handleMadInfoVariableTag(QXmlStreamReader &infoReader) const
+{
+    QPair<QString, QString> var;
+    if (infoReader.name() != QLatin1String("variable")) {
+        infoReader.skipCurrentElement();
+        return var;
+    }
+
+    // TODO: Check for "purpose" attribute and handle "glbackend" in a special way
+    while (infoReader.readNextStartElement()) {
+        if (infoReader.name() == QLatin1String("name"))
+            var.first = infoReader.readElementText();
+        else if (infoReader.name() == QLatin1String("value"))
+            var.second = infoReader.readElementText();
+        else
+            infoReader.skipCurrentElement();
+    }
+    return var;
+}
+
+MaemoPortList MaemoQemuManager::handleMadInfoTcpPortListTag(QXmlStreamReader &infoReader) const
+{
+    MaemoPortList ports;
+    while (infoReader.readNextStartElement()) {
+        const int port = handleMadInfoPortTag(infoReader);
+        if (port != -1 && port != 6666) // TODO: Remove second condition once MADDE has ssh tag
+            ports.addPort(port);
+    }
+    return ports;
+}
+
+int MaemoQemuManager::handleMadInfoPortTag(QXmlStreamReader &infoReader) const
+{
+    int port = -1;
+    if (infoReader.name() == QLatin1String("port")) {
+        while (infoReader.readNextStartElement()) {
+            if (infoReader.name() == QLatin1String("host"))
+                port = infoReader.readElementText().toInt();
+            else
+                infoReader.skipCurrentElement();
+        }
+    }
+    return port;
 }
 
 void MaemoQemuManager::notify(const QList<int> uniqueIds)
index 6222ea9..605af07 100644 (file)
@@ -43,6 +43,7 @@
 QT_FORWARD_DECLARE_CLASS(QAction);
 QT_FORWARD_DECLARE_CLASS(QFileSystemWatcher)
 QT_FORWARD_DECLARE_CLASS(QStringList);
+QT_FORWARD_DECLARE_CLASS(QXmlStreamReader);
 
 namespace ProjectExplorer {
     class BuildConfiguration;
@@ -56,6 +57,7 @@ namespace Qt4ProjectManager {
     namespace Internal {
     class MaemoRunConfiguration;
 
+// TODO: Rename to something more unique
 struct Runtime
 {
     Runtime() {}
@@ -65,6 +67,7 @@ struct Runtime
         return !m_bin.isEmpty();
     }
 
+    QString m_name;
     QString m_bin;
     QString m_root;
     QString m_args;
@@ -133,9 +136,20 @@ private:
     QString maddeRoot(const QString &qmake) const;
     QString targetRoot(const QString &qmake) const;
 
-    bool fillRuntimeInformation(Runtime *runtime) const;
+    bool fillRuntimeInformationForOldMadInfo(Runtime *runtime) const;
     void setEnvironment(Runtime *runTime, const QString &envSpec) const;
-    QString runtimeForQtVersion(const QString &qmakeCommand) const;
+    Runtime createRuntime(const QtVersion *qtVersion) const;
+    Runtime parseRuntimeFromMadInfo(const QByteArray &output,
+        const QString &targetName) const;
+    Runtime parseRuntimeFromOldMadInfo(const QString &output,
+        const QString &maddeRootPath, const QString &targetName) const;
+    void handleMadInfoTargetTag(QXmlStreamReader &infoReader,
+        QString &runtimeName, const QString &targetName) const;
+    Runtime handleMadInfoRuntimeTag(QXmlStreamReader &infoReader) const;
+    QHash<QString, QString> handleMadInfoEnvironmentTag(QXmlStreamReader &infoReader) const;
+    QPair<QString, QString> handleMadInfoVariableTag(QXmlStreamReader &infoReader) const;
+    MaemoPortList handleMadInfoTcpPortListTag(QXmlStreamReader &infoReader) const;
+    int handleMadInfoPortTag(QXmlStreamReader &infoReader) const;
 
     void notify(const QList<int> uniqueIds);
     void toggleDeviceConnections(MaemoRunConfiguration *mrc, bool connect);