/************************************************************************** ** ** Copyright (C) 2012 - 2014 BlackBerry Limited. All rights reserved. ** ** Contact: BlackBerry (qt@blackberry.com) ** Contact: KDAB (info@kdab.com) ** ** This file is part of Qt Creator. ** ** 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 Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ****************************************************************************/ #include "blackberrycreatepackagestep.h" #include "qnxconstants.h" #include "blackberrycreatepackagestepconfigwidget.h" #include "blackberrydeployconfiguration.h" #include "qnxutils.h" #include "blackberryqtversion.h" #include "blackberrydeviceconfiguration.h" #include "blackberrydeployinformation.h" #include "blackberrysigningpasswordsdialog.h" #include "bardescriptordocument.h" #include <debugger/debuggerrunconfigurationaspect.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/target.h> #include <projectexplorer/runconfiguration.h> #include <qmakeprojectmanager/qmakebuildconfiguration.h> #include <qmakeprojectmanager/qmakenodes.h> #include <qmakeprojectmanager/qmakeproject.h> #include <qtsupport/qtkitinformation.h> #include <utils/qtcassert.h> using namespace Qnx; using namespace Qnx::Internal; namespace { const char PACKAGER_CMD[] = "blackberry-nativepackager"; const char PACKAGE_MODE_KEY[] = "Qt4ProjectManager.BlackBerryCreatePackageStep.PackageMode"; const char CSK_PASSWORD_KEY[] = "Qt4ProjectManager.BlackBerryCreatePackageStep.CskPassword"; const char KEYSTORE_PASSWORD_KEY[] = "Qt4ProjectManager.BlackBerryCreatePackageStep.KeystorePassword"; const char SAVE_PASSWORDS_KEY[] = "Qt4ProjectManager.BlackBerryCreatePackageStep.SavePasswords"; } BlackBerryCreatePackageStep::BlackBerryCreatePackageStep(ProjectExplorer::BuildStepList *bsl) : BlackBerryAbstractDeployStep(bsl, Core::Id(Constants::QNX_CREATE_PACKAGE_BS_ID)) { ctor(); } BlackBerryCreatePackageStep::BlackBerryCreatePackageStep(ProjectExplorer::BuildStepList *bsl, BlackBerryCreatePackageStep *bs) : BlackBerryAbstractDeployStep(bsl, bs) { ctor(); } void BlackBerryCreatePackageStep::ctor() { setDisplayName(tr("Create packages")); m_packageMode = DevelopmentMode; } bool BlackBerryCreatePackageStep::init() { if (!BlackBerryAbstractDeployStep::init()) return false; const QString packageCmd = target()->activeBuildConfiguration()->environment().searchInPath(QLatin1String(PACKAGER_CMD)); if (packageCmd.isEmpty()) { raiseError(tr("Could not find packager command '%1' in the build environment") .arg(QLatin1String(PACKAGER_CMD))); return false; } BlackBerryDeployConfiguration *deployConfig = qobject_cast<BlackBerryDeployConfiguration *>(deployConfiguration()); QTC_ASSERT(deployConfig, return false); QList<BarPackageDeployInformation> packagesToDeploy = deployConfig->deploymentInfo()->enabledPackages(); if (packagesToDeploy.isEmpty()) { raiseError(tr("No packages enabled for deployment")); return false; } foreach (const BarPackageDeployInformation &info, packagesToDeploy) { if (info.appDescriptorPath().isEmpty()) { raiseError(tr("Application descriptor file not specified, please check deployment settings")); return false; } if (info.packagePath().isEmpty()) { raiseError(tr("No package specified, please check deployment settings")); return false; } const QString buildDir = QFileInfo(info.packagePath()).absolutePath(); QDir dir(buildDir); if (!dir.exists()) { if (!dir.mkpath(buildDir)) { raiseError(tr("Could not create build directory '%1'").arg(buildDir)); return false; } } const QString preparedFilePath = buildDir + QLatin1String("/bar-descriptor-") + project()->displayName() + QLatin1String("-qtc-generated.xml"); if (!prepareAppDescriptorFile(info.appDescriptorPath(), preparedFilePath)) // If there is an error, prepareAppDescriptorFile() will raise it return false; QStringList args; if (m_packageMode == DevelopmentMode) { args << QLatin1String("-devMode"); if (!debugToken().isEmpty()) args << QLatin1String("-debugToken") << QnxUtils::addQuotes(QDir::toNativeSeparators(debugToken())); } else if (m_packageMode == SigningPackageMode) { if (m_cskPassword.isEmpty() || m_keystorePassword.isEmpty()) { BlackBerrySigningPasswordsDialog dlg; dlg.setCskPassword(m_cskPassword); dlg.setStorePassword(m_keystorePassword); if (dlg.exec() == QDialog::Rejected) { raiseError(tr("Missing passwords for signing packages")); return false; } m_cskPassword = dlg.cskPassword(); m_keystorePassword = dlg.storePassword(); emit cskPasswordChanged(m_cskPassword); emit keystorePasswordChanged(m_keystorePassword); } args << QLatin1String("-sign"); args << QLatin1String("-cskpass"); args << m_cskPassword; args << QLatin1String("-storepass"); args << m_keystorePassword; } args << QLatin1String("-package") << QnxUtils::addQuotes(QDir::toNativeSeparators(info.packagePath())); args << QnxUtils::addQuotes(QDir::toNativeSeparators(preparedFilePath)); addCommand(packageCmd, args); } return true; } ProjectExplorer::BuildStepConfigWidget *BlackBerryCreatePackageStep::createConfigWidget() { return new BlackBerryCreatePackageStepConfigWidget(this); } QString BlackBerryCreatePackageStep::debugToken() const { BlackBerryDeviceConfiguration::ConstPtr device = BlackBerryDeviceConfiguration::device(target()->kit()); if (!device) return QString(); return device->debugToken(); } bool BlackBerryCreatePackageStep::fromMap(const QVariantMap &map) { m_packageMode = static_cast<PackageMode>(map.value(QLatin1String(PACKAGE_MODE_KEY), DevelopmentMode).toInt()); m_savePasswords = map.value(QLatin1String(SAVE_PASSWORDS_KEY), false).toBool(); if (m_savePasswords) { m_cskPassword = map.value(QLatin1String(CSK_PASSWORD_KEY)).toString(); m_keystorePassword = map.value(QLatin1String(KEYSTORE_PASSWORD_KEY)).toString(); } return BlackBerryAbstractDeployStep::fromMap(map); } QVariantMap BlackBerryCreatePackageStep::toMap() const { QVariantMap map = BlackBerryAbstractDeployStep::toMap(); map.insert(QLatin1String(PACKAGE_MODE_KEY), m_packageMode); map.insert(QLatin1String(SAVE_PASSWORDS_KEY), m_savePasswords); if (m_savePasswords) { map.insert(QLatin1String(CSK_PASSWORD_KEY), m_cskPassword); map.insert(QLatin1String(KEYSTORE_PASSWORD_KEY), m_keystorePassword); } return map; } BlackBerryCreatePackageStep::PackageMode BlackBerryCreatePackageStep::packageMode() const { return m_packageMode; } QString BlackBerryCreatePackageStep::cskPassword() const { return m_cskPassword; } QString BlackBerryCreatePackageStep::keystorePassword() const { return m_keystorePassword; } bool BlackBerryCreatePackageStep::savePasswords() const { return m_savePasswords; } void BlackBerryCreatePackageStep::setPackageMode(BlackBerryCreatePackageStep::PackageMode packageMode) { m_packageMode = packageMode; } void BlackBerryCreatePackageStep::setCskPassword(const QString &cskPassword) { m_cskPassword = cskPassword; } void BlackBerryCreatePackageStep::setKeystorePassword(const QString &storePassword) { m_keystorePassword = storePassword; } void BlackBerryCreatePackageStep::setSavePasswords(bool savePasswords) { m_savePasswords = savePasswords; } static void addQtInfoPlaceHolderToHash(QHash<QString, QString> &hash, const BlackBerryQtVersion *qtVersion, const char *key) { hash[QLatin1Char('%') + QString::fromLatin1(key) + QLatin1Char('%')] = qtVersion->versionInfo().value(QLatin1String(key)); } bool BlackBerryCreatePackageStep::prepareAppDescriptorFile(const QString &appDescriptorPath, const QString &preparedFilePath) { BlackBerryQtVersion *qtVersion = dynamic_cast<BlackBerryQtVersion *>(QtSupport::QtKitInformation::qtVersion(target()->kit())); if (!qtVersion) { raiseError(tr("Error preparing application descriptor file")); return false; } BarDescriptorDocument doc; QString errorString; if (!doc.open(&errorString, appDescriptorPath)) { raiseError(tr("Error opening application descriptor file '%1' - %2") .arg(QDir::toNativeSeparators(appDescriptorPath)) .arg(errorString)); return false; } // Add Warning text const QString warningText = QString::fromLatin1("This file is autogenerated," " any changes will get overwritten if deploying with Qt Creator"); doc.setBannerComment(warningText); // Replace Qt path placeholders QHash<QString, QString> placeHoldersHash; addQtInfoPlaceHolderToHash(placeHoldersHash, qtVersion, "QT_INSTALL_LIBS"); addQtInfoPlaceHolderToHash(placeHoldersHash, qtVersion, "QT_INSTALL_PLUGINS"); addQtInfoPlaceHolderToHash(placeHoldersHash, qtVersion, "QT_INSTALL_IMPORTS"); addQtInfoPlaceHolderToHash(placeHoldersHash, qtVersion, "QT_INSTALL_QML"); //Replace Source path placeholder placeHoldersHash[QLatin1String("%SRC_DIR%")] = QDir::toNativeSeparators(target()->project()->projectDirectory()); doc.expandPlaceHolders(placeHoldersHash); QStringList commandLineArguments = doc.value(BarDescriptorDocument::arg).toStringList(); QStringList extraCommandLineArguments; // Add parameter for QML debugging (if enabled) Debugger::DebuggerRunConfigurationAspect *aspect = target()->activeRunConfiguration()->extraAspect<Debugger::DebuggerRunConfigurationAspect>(); if (aspect->useQmlDebugger()) { bool qmljsdebuggerExists = false; foreach (const QString &s, commandLineArguments) { if (s.startsWith(QLatin1String("-qmljsdebugger="))) { qmljsdebuggerExists = true; break; } } if (!qmljsdebuggerExists) { extraCommandLineArguments << QString::fromLatin1("-qmljsdebugger=port:%1") .arg(aspect->qmlDebugServerPort()); } } if (extraCommandLineArguments.count()) { commandLineArguments << extraCommandLineArguments; doc.setValue(BarDescriptorDocument::arg, commandLineArguments); } doc.setFilePath(preparedFilePath); if (!doc.save(&errorString)) { raiseError(tr("Error saving prepared application descriptor file '%1' - %2") .arg(QDir::toNativeSeparators(preparedFilePath)) .arg(errorString)); return false; } return true; } void BlackBerryCreatePackageStep::processStarted(const ProjectExplorer::ProcessParameters ¶ms) { if (m_packageMode == SigningPackageMode) { QString arguments = params.prettyArguments(); const QString cskPasswordLine = QLatin1String(" -cskpass ") + m_cskPassword; const QString hiddenCskPasswordLine = QLatin1String(" -cskpass <hidden>"); arguments.replace(cskPasswordLine, hiddenCskPasswordLine); const QString storePasswordLine = QLatin1String(" -storepass ") + m_keystorePassword; const QString hiddenStorePasswordLine = QLatin1String(" -storepass <hidden>"); arguments.replace(storePasswordLine, hiddenStorePasswordLine); emitOutputInfo(params, arguments); } else { BlackBerryAbstractDeployStep::processStarted(params); } }