summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBogDan Vatra <bogdan@kde.org>2014-06-25 15:42:11 +0200
committerDaniel Teske <daniel.teske@digia.com>2014-07-21 12:41:28 +0200
commit64e5a543a845d8d800504206a42c58d4e28ac89c (patch)
tree205faff83b9fb890c65309fe4c7cc7878826f515 /src
parent4657ac7452662d19823412e82d599bf4079a3c4d (diff)
downloadqt-creator-64e5a543a845d8d800504206a42c58d4e28ac89c.tar.gz
Move qmake specific part to qmake plugin, generalize android support
- Split up androiddeployqt into two steps: One building the apk, and one deploying it to the device. - The build apk step base class AndroidBuildApkStep is ihneritaged by the qmake specific class QmakeAndroidBuildApkStep. - The deployment step is still called androiddeployqt - Move all qmake specific code to the qmakeprojectmanager plguin - Flip the depencency between the android and qmake plugin, now the qmake plugin depends on the android plugin, implementing a interface the android plugin provides. - Note: This removes the debug deployment for now. Change-Id: I1c386640159ed14b637668abde8eb3b9009ab803 Reviewed-by: BogDan Vatra <bogdan@kde.org>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/android/android.pro22
-rw-r--r--src/plugins/android/android.qbs30
-rw-r--r--src/plugins/android/android_dependencies.pri1
-rw-r--r--src/plugins/android/androidanalyzesupport.h1
-rw-r--r--src/plugins/android/androidbuildapkstep.cpp313
-rw-r--r--src/plugins/android/androidbuildapkstep.h117
-rw-r--r--src/plugins/android/androidbuildapkwidget.cpp238
-rw-r--r--src/plugins/android/androidbuildapkwidget.h82
-rw-r--r--src/plugins/android/androidbuildapkwidget.ui228
-rw-r--r--src/plugins/android/androidconfigurations.cpp8
-rw-r--r--src/plugins/android/androidconfigurations.h11
-rw-r--r--src/plugins/android/androidconstants.h5
-rw-r--r--src/plugins/android/androiddebugsupport.h1
-rw-r--r--src/plugins/android/androiddeployconfiguration.cpp11
-rw-r--r--src/plugins/android/androiddeployqtstep.cpp377
-rw-r--r--src/plugins/android/androiddeployqtstep.h69
-rw-r--r--src/plugins/android/androiddeployqtwidget.cpp282
-rw-r--r--src/plugins/android/androiddeployqtwidget.h27
-rw-r--r--src/plugins/android/androiddeployqtwidget.ui353
-rw-r--r--src/plugins/android/androiddevice.h5
-rw-r--r--src/plugins/android/androidglobal.h20
-rw-r--r--src/plugins/android/androidmanager.cpp124
-rw-r--r--src/plugins/android/androidmanager.h30
-rw-r--r--src/plugins/android/androidmanifesteditorwidget.cpp8
-rw-r--r--src/plugins/android/androidplugin.cpp14
-rw-r--r--src/plugins/android/androidqtsupport.h5
-rw-r--r--src/plugins/android/androidqtversion.cpp11
-rw-r--r--src/plugins/android/androidruncontrol.h1
-rw-r--r--src/plugins/android/androidrunner.h1
-rw-r--r--src/plugins/android/avddialog.h3
-rw-r--r--src/plugins/projectexplorer/settingsaccessor.cpp250
-rw-r--r--src/plugins/qmakeprojectmanager/androidextralibrarylistmodel.cpp (renamed from src/plugins/android/androidextralibrarylistmodel.cpp)2
-rw-r--r--src/plugins/qmakeprojectmanager/androidextralibrarylistmodel.h (renamed from src/plugins/android/androidextralibrarylistmodel.h)4
-rw-r--r--src/plugins/qmakeprojectmanager/androidpackageinstallationfactory.cpp (renamed from src/plugins/android/androidpackageinstallationfactory.cpp)11
-rw-r--r--src/plugins/qmakeprojectmanager/androidpackageinstallationfactory.h (renamed from src/plugins/android/androidpackageinstallationfactory.h)2
-rw-r--r--src/plugins/qmakeprojectmanager/androidpackageinstallationstep.cpp (renamed from src/plugins/android/androidpackageinstallationstep.cpp)37
-rw-r--r--src/plugins/qmakeprojectmanager/androidpackageinstallationstep.h (renamed from src/plugins/android/androidpackageinstallationstep.h)9
-rw-r--r--src/plugins/qmakeprojectmanager/androidqmakebuildconfigurationfactory.cpp (renamed from src/plugins/android/qmakeandroidsupport.cpp)62
-rw-r--r--src/plugins/qmakeprojectmanager/androidqmakebuildconfigurationfactory.h59
-rw-r--r--src/plugins/qmakeprojectmanager/createandroidmanifestwizard.cpp (renamed from src/plugins/android/createandroidmanifestwizard.cpp)18
-rw-r--r--src/plugins/qmakeprojectmanager/createandroidmanifestwizard.h (renamed from src/plugins/android/createandroidmanifestwizard.h)7
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeandroidbuildapkstep.cpp293
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeandroidbuildapkstep.h101
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeandroidbuildapkwidget.cpp190
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeandroidbuildapkwidget.h85
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeandroidbuildapkwidget.ui149
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeandroidrunconfiguration.cpp (renamed from src/plugins/android/qmakeandroidrunconfiguration.cpp)2
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeandroidrunconfiguration.h (renamed from src/plugins/android/qmakeandroidrunconfiguration.h)6
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeandroidrunfactories.cpp (renamed from src/plugins/android/qmakeandroidrunfactories.cpp)3
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeandroidrunfactories.h (renamed from src/plugins/android/qmakeandroidrunfactories.h)2
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeandroidsupport.cpp133
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeandroidsupport.h (renamed from src/plugins/android/qmakeandroidsupport.h)10
-rw-r--r--src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp1
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro27
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs11
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectmanager_dependencies.pri4
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp12
57 files changed, 2612 insertions, 1276 deletions
diff --git a/src/plugins/android/android.pro b/src/plugins/android/android.pro
index 230c410104..9bb43171f2 100644
--- a/src/plugins/android/android.pro
+++ b/src/plugins/android/android.pro
@@ -16,8 +16,6 @@ HEADERS += \
androidsettingspage.h \
androidsettingswidget.h \
androidtoolchain.h \
- androidpackageinstallationstep.h \
- androidpackageinstallationfactory.h \
androiderrormessage.h \
androidglobal.h \
androidrunner.h \
@@ -41,9 +39,7 @@ HEADERS += \
androiddeployqtstep.h \
certificatesmodel.h \
androiddeployqtwidget.h \
- createandroidmanifestwizard.h \
androidpotentialkit.h \
- androidextralibrarylistmodel.h \
androidsignaloperation.h \
javaeditor.h \
javaeditorfactory.h \
@@ -53,9 +49,8 @@ HEADERS += \
javafilewizard.h \
avddialog.h \
android_global.h \
- qmakeandroidsupport.h \
- qmakeandroidrunfactories.h \
- qmakeandroidrunconfiguration.h
+ androidbuildapkstep.h \
+ androidbuildapkwidget.h
SOURCES += \
androidconfigurations.cpp \
@@ -66,8 +61,6 @@ SOURCES += \
androidsettingspage.cpp \
androidsettingswidget.cpp \
androidtoolchain.cpp \
- androidpackageinstallationstep.cpp \
- androidpackageinstallationfactory.cpp \
androiderrormessage.cpp \
androidrunner.cpp \
androiddebugsupport.cpp \
@@ -90,9 +83,7 @@ SOURCES += \
androiddeployqtstep.cpp \
certificatesmodel.cpp \
androiddeployqtwidget.cpp \
- createandroidmanifestwizard.cpp \
androidpotentialkit.cpp \
- androidextralibrarylistmodel.cpp \
androidsignaloperation.cpp \
javaeditor.cpp \
javaeditorfactory.cpp \
@@ -101,16 +92,17 @@ SOURCES += \
javacompletionassistprovider.cpp \
javafilewizard.cpp \
avddialog.cpp \
- qmakeandroidsupport.cpp \
- qmakeandroidrunfactories.cpp \
- qmakeandroidrunconfiguration.cpp
+ androidbuildapkstep.cpp \
+ androidbuildapkwidget.cpp
FORMS += \
androidsettingswidget.ui \
addnewavddialog.ui \
androidcreatekeystorecertificate.ui \
androiddevicedialog.ui \
- androiddeployqtwidget.ui
+ androiddeployqtwidget.ui \
+ androidbuildapkwidget.ui
RESOURCES = android.qrc
+
DEFINES += ANDROID_LIBRARY
diff --git a/src/plugins/android/android.qbs b/src/plugins/android/android.qbs
index e247a04e3f..30ac7a10d7 100644
--- a/src/plugins/android/android.qbs
+++ b/src/plugins/android/android.qbs
@@ -5,19 +5,15 @@ import QtcPlugin
QtcPlugin {
name: "Android"
+ Depends { name: "Qt"; submodules: ["widgets", "xml", "network"] }
+ Depends { name: "AnalyzerBase" }
Depends { name: "Core" }
- Depends { name: "ProjectExplorer" }
- Depends { name: "QmakeProjectManager" }
Depends { name: "Debugger" }
+ Depends { name: "ProjectExplorer" }
Depends { name: "QmlDebug" }
Depends { name: "QtSupport" }
Depends { name: "TextEditor" }
- Depends { name: "AnalyzerBase" }
Depends { name: "Utils" }
- Depends { name: "Qt"; submodules: ["widgets", "xml", "network"] }
-
- property bool enable: false
- pluginspecreplacements: ({"ANDROID_EXPERIMENTAL_STR": (enable ? "false": "true")})
files: [
"android_global.h",
@@ -31,6 +27,11 @@ QtcPlugin {
"androidcreatekeystorecertificate.cpp",
"androidcreatekeystorecertificate.h",
"androidcreatekeystorecertificate.ui",
+ "androidbuildapkstep.cpp",
+ "androidbuildapkstep.h",
+ "androidbuildapkwidget.cpp",
+ "androidbuildapkwidget.h",
+ "androidbuildapkwidget.ui",
"androiddeployqtstep.cpp",
"androiddeployqtstep.h",
"androiddebugsupport.cpp",
@@ -49,8 +50,6 @@ QtcPlugin {
"androiddevicefactory.h",
"androiderrormessage.h",
"androiderrormessage.cpp",
- "androidextralibrarylistmodel.cpp",
- "androidextralibrarylistmodel.h",
"androidgdbserverkitinformation.cpp",
"androidgdbserverkitinformation.h",
"androidglobal.h",
@@ -64,10 +63,6 @@ QtcPlugin {
"androidmanifesteditorfactory.h",
"androidmanifesteditorwidget.cpp",
"androidmanifesteditorwidget.h",
- "androidpackageinstallationfactory.cpp",
- "androidpackageinstallationfactory.h",
- "androidpackageinstallationstep.cpp",
- "androidpackageinstallationstep.h",
"androidplugin.cpp",
"androidplugin.h",
"androidpotentialkit.cpp",
@@ -100,8 +95,6 @@ QtcPlugin {
"avddialog.h",
"certificatesmodel.cpp",
"certificatesmodel.h",
- "createandroidmanifestwizard.cpp",
- "createandroidmanifestwizard.h",
"javaautocompleter.cpp",
"javaautocompleter.h",
"javacompletionassistprovider.cpp",
@@ -116,12 +109,5 @@ QtcPlugin {
"javaindenter.h",
"javaparser.cpp",
"javaparser.h",
- "qmakeandroidrunconfiguration.cpp",
- "qmakeandroidrunconfiguration.h",
- "qmakeandroidrunfactories.cpp",
- "qmakeandroidrunfactories.h",
- "qmakeandroidsupport.cpp",
- "qmakeandroidsupport.h",
-
]
}
diff --git a/src/plugins/android/android_dependencies.pri b/src/plugins/android/android_dependencies.pri
index 0064a8319e..94fa4d8f36 100644
--- a/src/plugins/android/android_dependencies.pri
+++ b/src/plugins/android/android_dependencies.pri
@@ -3,7 +3,6 @@ QTC_PLUGIN_DEPENDS += \
coreplugin \
debugger \
projectexplorer \
- qmakeprojectmanager \
qtsupport \
texteditor \
analyzerbase
diff --git a/src/plugins/android/androidanalyzesupport.h b/src/plugins/android/androidanalyzesupport.h
index 15db38589a..1a0c3b3489 100644
--- a/src/plugins/android/androidanalyzesupport.h
+++ b/src/plugins/android/androidanalyzesupport.h
@@ -40,7 +40,6 @@ namespace Android {
class AndroidRunConfiguration;
namespace Internal {
-
class AndroidRunner;
class AndroidAnalyzeSupport : public AndroidRunSupport
diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp
new file mode 100644
index 0000000000..f2e6539458
--- /dev/null
+++ b/src/plugins/android/androidbuildapkstep.cpp
@@ -0,0 +1,313 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 BogDan Vatra <bog_dan_ro@yahoo.com>
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 "androidbuildapkstep.h"
+#include "androidbuildapkwidget.h"
+#include "androidconfigurations.h"
+#include "androidconstants.h"
+#include "androidmanager.h"
+#include "androidqtsupport.h"
+#include "certificatesmodel.h"
+
+#include "javaparser.h"
+
+#include <coreplugin/fileutils.h>
+#include <coreplugin/icore.h>
+
+#include <projectexplorer/buildconfiguration.h>
+#include <projectexplorer/project.h>
+#include <projectexplorer/target.h>
+
+#include <qtsupport/qtkitinformation.h>
+
+#include <utils/qtcprocess.h>
+
+#include <QInputDialog>
+#include <QMessageBox>
+
+namespace Android {
+using namespace Internal;
+
+const QLatin1String DeployActionKey("Qt4ProjectManager.AndroidDeployQtStep.DeployQtAction");
+const QLatin1String KeystoreLocationKey("KeystoreLocation");
+const QLatin1String BuildTargetSdkKey("BuildTargetSdk");
+const QLatin1String VerboseOutputKey("VerboseOutput");
+
+AndroidBuildApkStep::AndroidBuildApkStep(ProjectExplorer::BuildStepList *parent, const Core::Id id)
+ : ProjectExplorer::AbstractProcessStep(parent, id),
+ m_deployAction(BundleLibrariesDeployment),
+ m_signPackage(false),
+ m_verbose(false),
+ m_openPackageLocation(false),
+ m_buildTargetSdk(AndroidConfig::apiLevelNameFor(AndroidConfigurations::currentConfig().highestAndroidSdk()))
+{
+ //: AndroidBuildApkStep default display name
+ setDefaultDisplayName(tr("Build Android APK"));
+}
+
+AndroidBuildApkStep::AndroidBuildApkStep(ProjectExplorer::BuildStepList *parent,
+ AndroidBuildApkStep *other)
+ : ProjectExplorer::AbstractProcessStep(parent, other),
+ m_deployAction(other->deployAction()),
+ m_signPackage(other->signPackage()),
+ m_verbose(other->m_verbose),
+ m_openPackageLocation(other->m_openPackageLocation),
+ m_buildTargetSdk(other->m_buildTargetSdk)
+{
+
+}
+
+bool AndroidBuildApkStep::init()
+{
+ ProjectExplorer::BuildConfiguration *bc = buildConfiguration();
+
+ if (m_signPackage) {
+ // check keystore and certificate passwords
+ while (!AndroidManager::checkKeystorePassword(m_keystorePath.toString(), m_keystorePasswd)) {
+ if (!keystorePassword())
+ return false; // user canceled
+ }
+
+ while (!AndroidManager::checkCertificatePassword(m_keystorePath.toString(), m_keystorePasswd, m_certificateAlias, m_certificatePasswd)) {
+ if (!certificatePassword())
+ return false; // user canceled
+ }
+
+
+ if (bc->buildType() == ProjectExplorer::BuildConfiguration::Debug)
+ emit addOutput(tr("Warning: Signing a debug package."), BuildStep::ErrorMessageOutput);
+ }
+
+ QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit());
+ if (!version)
+ return false;
+
+ JavaParser *parser = new JavaParser;
+ parser->setProjectFileList(target()->project()->files(ProjectExplorer::Project::AllFiles));
+ parser->setSourceDirectory(androidPackageSourceDir());
+ parser->setBuildDirectory(Utils::FileName::fromString(bc->buildDirectory().appendPath(QLatin1String(Constants::ANDROID_BUILDDIRECTORY)).toString()));
+ setOutputParser(parser);
+
+ m_openPackageLocationForRun = m_openPackageLocation;
+ m_apkPath = AndroidManager::androidQtSupport(target())->apkPath(target(), m_signPackage ? AndroidQtSupport::ReleaseBuildSigned
+ : AndroidQtSupport::DebugBuild).toString();
+
+ bool result = AbstractProcessStep::init();
+ if (!result)
+ return false;
+
+ return true;
+}
+
+void AndroidBuildApkStep::showInGraphicalShell()
+{
+ Core::FileUtils::showInGraphicalShell(Core::ICore::instance()->mainWindow(), m_apkPath);
+}
+
+ProjectExplorer::BuildStepConfigWidget *AndroidBuildApkStep::createConfigWidget()
+{
+ return new AndroidBuildApkWidget(this);
+}
+
+void AndroidBuildApkStep::processFinished(int exitCode, QProcess::ExitStatus status)
+{
+ AbstractProcessStep::processFinished(exitCode, status);
+ if (m_openPackageLocationForRun && status == QProcess::NormalExit && exitCode == 0)
+ QMetaObject::invokeMethod(this, "showInGraphicalShell", Qt::QueuedConnection);
+}
+
+bool AndroidBuildApkStep::fromMap(const QVariantMap &map)
+{
+ m_deployAction = AndroidDeployAction(map.value(DeployActionKey, BundleLibrariesDeployment).toInt());
+ if ( m_deployAction == DebugDeployment
+ && QtSupport::QtKitInformation::qtVersion(target()->kit())->qtVersion() < QtSupport::QtVersionNumber(5, 4, 0)) {
+ m_deployAction = BundleLibrariesDeployment;
+ }
+
+ m_keystorePath = Utils::FileName::fromString(map.value(KeystoreLocationKey).toString());
+ m_signPackage = false; // don't restore this
+ m_buildTargetSdk = map.value(BuildTargetSdkKey).toString();
+ if (m_buildTargetSdk.isEmpty())
+ m_buildTargetSdk = AndroidConfig::apiLevelNameFor(AndroidConfigurations::currentConfig().highestAndroidSdk());
+ m_verbose = map.value(VerboseOutputKey).toBool();
+ return ProjectExplorer::BuildStep::fromMap(map);
+}
+
+QVariantMap AndroidBuildApkStep::toMap() const
+{
+ QVariantMap map = ProjectExplorer::AbstractProcessStep::toMap();
+ map.insert(DeployActionKey, m_deployAction);
+ map.insert(KeystoreLocationKey, m_keystorePath.toString());
+ map.insert(BuildTargetSdkKey, m_buildTargetSdk);
+ map.insert(VerboseOutputKey, m_verbose);
+ return map;
+}
+
+Utils::FileName AndroidBuildApkStep::keystorePath()
+{
+ return m_keystorePath;
+}
+
+QString AndroidBuildApkStep::buildTargetSdk() const
+{
+ return m_buildTargetSdk;
+}
+
+void AndroidBuildApkStep::setBuildTargetSdk(const QString &sdk)
+{
+ m_buildTargetSdk = sdk;
+}
+
+AndroidBuildApkStep::AndroidDeployAction AndroidBuildApkStep::deployAction() const
+{
+ return m_deployAction;
+}
+
+void AndroidBuildApkStep::setDeployAction(AndroidDeployAction deploy)
+{
+ m_deployAction = deploy;
+}
+
+void AndroidBuildApkStep::setKeystorePath(const Utils::FileName &path)
+{
+ m_keystorePath = path;
+ m_certificatePasswd.clear();
+ m_keystorePasswd.clear();
+}
+
+void AndroidBuildApkStep::setKeystorePassword(const QString &pwd)
+{
+ m_keystorePasswd = pwd;
+}
+
+void AndroidBuildApkStep::setCertificateAlias(const QString &alias)
+{
+ m_certificateAlias = alias;
+}
+
+void AndroidBuildApkStep::setCertificatePassword(const QString &pwd)
+{
+ m_certificatePasswd = pwd;
+}
+
+bool AndroidBuildApkStep::signPackage() const
+{
+ return m_signPackage;
+}
+
+void AndroidBuildApkStep::setSignPackage(bool b)
+{
+ m_signPackage = b;
+}
+
+bool AndroidBuildApkStep::openPackageLocation() const
+{
+ return m_openPackageLocation;
+}
+
+void AndroidBuildApkStep::setOpenPackageLocation(bool open)
+{
+ m_openPackageLocation = open;
+}
+
+void AndroidBuildApkStep::setVerboseOutput(bool verbose)
+{
+ m_verbose = verbose;
+}
+
+bool AndroidBuildApkStep::runInGuiThread() const
+{
+ return true;
+}
+
+bool AndroidBuildApkStep::verboseOutput() const
+{
+ return m_verbose;
+}
+
+QAbstractItemModel *AndroidBuildApkStep::keystoreCertificates()
+{
+ QString rawCerts;
+ QProcess keytoolProc;
+ while (!rawCerts.length() || !m_keystorePasswd.length()) {
+ QStringList params;
+ params << QLatin1String("-list") << QLatin1String("-v") << QLatin1String("-keystore") << m_keystorePath.toUserOutput() << QLatin1String("-storepass");
+ if (!m_keystorePasswd.length())
+ keystorePassword();
+ if (!m_keystorePasswd.length())
+ return 0;
+ params << m_keystorePasswd;
+ params << QLatin1String("-J-Duser.language=en");
+ keytoolProc.start(AndroidConfigurations::currentConfig().keytoolPath().toString(), params);
+ if (!keytoolProc.waitForStarted() || !keytoolProc.waitForFinished()) {
+ QMessageBox::critical(0, tr("Error"),
+ tr("Failed to run keytool."));
+ return 0;
+ }
+
+ if (keytoolProc.exitCode()) {
+ QMessageBox::critical(0, tr("Error"),
+ tr("Invalid password."));
+ m_keystorePasswd.clear();
+ }
+ rawCerts = QString::fromLatin1(keytoolProc.readAllStandardOutput());
+ }
+ return new CertificatesModel(rawCerts, this);
+}
+
+bool AndroidBuildApkStep::keystorePassword()
+{
+ m_keystorePasswd.clear();
+ bool ok;
+ QString text = QInputDialog::getText(0, tr("Keystore"),
+ tr("Keystore password:"), QLineEdit::Password,
+ QString(), &ok);
+ if (ok && !text.isEmpty()) {
+ m_keystorePasswd = text;
+ return true;
+ }
+ return false;
+}
+
+bool AndroidBuildApkStep::certificatePassword()
+{
+ m_certificatePasswd.clear();
+ bool ok;
+ QString text = QInputDialog::getText(0, tr("Certificate"),
+ tr("Certificate password (%1):").arg(m_certificateAlias), QLineEdit::Password,
+ QString(), &ok);
+ if (ok && !text.isEmpty()) {
+ m_certificatePasswd = text;
+ return true;
+ }
+ return false;
+}
+
+} // namespace Android
diff --git a/src/plugins/android/androidbuildapkstep.h b/src/plugins/android/androidbuildapkstep.h
new file mode 100644
index 0000000000..668f5b4b7e
--- /dev/null
+++ b/src/plugins/android/androidbuildapkstep.h
@@ -0,0 +1,117 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 BogDan Vatra <bog_dan_ro@yahoo.com>
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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.
+**
+****************************************************************************/
+
+#ifndef ANDROIDBUILDAPKSTEP_H
+#define ANDROIDBUILDAPKSTEP_H
+
+#include "android_global.h"
+#include <projectexplorer/abstractprocessstep.h>
+#include <qtsupport/baseqtversion.h>
+
+QT_BEGIN_NAMESPACE
+class QAbstractItemModel;
+QT_END_NAMESPACE
+
+namespace Android {
+
+class ANDROID_EXPORT AndroidBuildApkStep : public ProjectExplorer::AbstractProcessStep
+{
+ Q_OBJECT
+public:
+ AndroidBuildApkStep(ProjectExplorer::BuildStepList *bc, const Core::Id id);
+
+ enum AndroidDeployAction
+ {
+ MinistroDeployment, // use ministro
+ DebugDeployment,
+ BundleLibrariesDeployment
+ };
+
+ bool fromMap(const QVariantMap &map);
+ QVariantMap toMap() const;
+
+ AndroidDeployAction deployAction() const;
+
+ // signing
+ Utils::FileName keystorePath();
+ void setKeystorePath(const Utils::FileName &path);
+ void setKeystorePassword(const QString &pwd);
+ void setCertificateAlias(const QString &alias);
+ void setCertificatePassword(const QString &pwd);
+
+ QAbstractItemModel *keystoreCertificates();
+ bool signPackage() const;
+ void setSignPackage(bool b);
+
+ bool openPackageLocation() const;
+ void setOpenPackageLocation(bool open);
+ bool verboseOutput() const;
+ void setVerboseOutput(bool verbose);
+
+ bool runInGuiThread() const;
+
+ QString buildTargetSdk() const;
+ void setBuildTargetSdk(const QString &sdk);
+public slots:
+ void setDeployAction(AndroidDeployAction deploy);
+
+protected slots:
+ void showInGraphicalShell();
+
+protected:
+ AndroidBuildApkStep(ProjectExplorer::BuildStepList *bc,
+ AndroidBuildApkStep *other);
+ bool keystorePassword();
+ bool certificatePassword();
+
+ bool init();
+ ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
+ bool immutable() const { return true; }
+ void processFinished(int exitCode, QProcess::ExitStatus status);
+ virtual Utils::FileName androidPackageSourceDir() const = 0;
+
+protected:
+ AndroidDeployAction m_deployAction;
+ bool m_signPackage;
+ bool m_verbose;
+ bool m_openPackageLocation;
+ bool m_openPackageLocationForRun;
+ QString m_buildTargetSdk;
+
+ Utils::FileName m_keystorePath;
+ QString m_keystorePasswd;
+ QString m_certificateAlias;
+ QString m_certificatePasswd;
+ QString m_apkPath;
+};
+
+} // namespace Android
+
+#endif // ANDROIDBUILDAPKSTEP_H
diff --git a/src/plugins/android/androidbuildapkwidget.cpp b/src/plugins/android/androidbuildapkwidget.cpp
new file mode 100644
index 0000000000..fb45115949
--- /dev/null
+++ b/src/plugins/android/androidbuildapkwidget.cpp
@@ -0,0 +1,238 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 BogDan Vatra <bog_dan_ro@yahoo.com>
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 "androidbuildapkstep.h"
+#include "androidbuildapkwidget.h"
+#include "androidconfigurations.h"
+#include "androidcreatekeystorecertificate.h"
+#include "androidmanager.h"
+#include "ui_androidbuildapkwidget.h"
+
+#include <projectexplorer/buildconfiguration.h>
+#include <projectexplorer/project.h>
+#include <projectexplorer/target.h>
+#include <qtsupport/qtkitinformation.h>
+
+#include <utils/fancylineedit.h>
+#include <utils/pathchooser.h>
+
+#include <QFileDialog>
+
+#include <algorithm>
+
+using namespace Android;
+using namespace Internal;
+
+AndroidBuildApkWidget::AndroidBuildApkWidget(AndroidBuildApkStep *step)
+ : ProjectExplorer::BuildStepConfigWidget(),
+ m_ui(new Ui::AndroidBuildApkWidget),
+ m_step(step)
+{
+ m_ui->setupUi(this);
+
+ // Target sdk combobox
+ int minApiLevel = 9;
+ QStringList targets = AndroidConfig::apiLevelNamesFor(AndroidConfigurations::currentConfig().sdkTargets(minApiLevel));
+ m_ui->targetSDKComboBox->addItems(targets);
+ m_ui->targetSDKComboBox->setCurrentIndex(targets.indexOf(AndroidManager::buildTargetSDK(step->target())));
+
+ // deployment option
+ switch (m_step->deployAction()) {
+ case AndroidBuildApkStep::MinistroDeployment:
+ m_ui->ministroOption->setChecked(true);
+ break;
+ case AndroidBuildApkStep::DebugDeployment:
+ m_ui->temporaryQtOption->setChecked(true);
+ break;
+ case AndroidBuildApkStep::BundleLibrariesDeployment:
+ m_ui->bundleQtOption->setChecked(true);
+ break;
+ default:
+ // can't happen
+ break;
+ }
+
+ // signing
+ m_ui->signPackageCheckBox->setChecked(m_step->signPackage());
+ m_ui->KeystoreLocationPathChooser->setExpectedKind(Utils::PathChooser::File);
+ m_ui->KeystoreLocationPathChooser->lineEdit()->setReadOnly(true);
+ m_ui->KeystoreLocationPathChooser->setPath(m_step->keystorePath().toUserOutput());
+ m_ui->KeystoreLocationPathChooser->setInitialBrowsePathBackup(QDir::homePath());
+ m_ui->KeystoreLocationPathChooser->setPromptDialogFilter(tr("Keystore files (*.keystore *.jks)"));
+ m_ui->KeystoreLocationPathChooser->setPromptDialogTitle(tr("Select Keystore File"));
+ m_ui->signingDebugWarningIcon->hide();
+ m_ui->signingDebugWarningLabel->hide();
+ signPackageCheckBoxToggled(m_step->signPackage());
+
+ m_ui->verboseOutputCheckBox->setChecked(m_step->verboseOutput());
+ m_ui->openPackageLocationCheckBox->setChecked(m_step->openPackageLocation());
+
+ // target sdk
+ connect(m_ui->targetSDKComboBox, SIGNAL(activated(QString)), SLOT(setTargetSdk(QString)));
+
+ // deployment options
+ connect(m_ui->ministroOption, SIGNAL(clicked()), SLOT(setMinistro()));
+ connect(m_ui->temporaryQtOption, SIGNAL(clicked()), SLOT(setDeployLocalQtLibs()));
+ connect(m_ui->bundleQtOption, SIGNAL(clicked()), SLOT(setBundleQtLibs()));
+
+ connect(m_ui->openPackageLocationCheckBox, SIGNAL(toggled(bool)),
+ this, SLOT(openPackageLocationCheckBoxToggled(bool)));
+ connect(m_ui->verboseOutputCheckBox, SIGNAL(toggled(bool)),
+ this, SLOT(verboseOutputCheckBoxToggled(bool)));
+
+ //signing
+ connect(m_ui->signPackageCheckBox, SIGNAL(toggled(bool)),
+ this, SLOT(signPackageCheckBoxToggled(bool)));
+ connect(m_ui->KeystoreCreatePushButton, SIGNAL(clicked()),
+ this, SLOT(createKeyStore()));
+ connect(m_ui->KeystoreLocationPathChooser, SIGNAL(pathChanged(QString)),
+ SLOT(updateKeyStorePath(QString)));
+ connect(m_ui->certificatesAliasComboBox, SIGNAL(activated(QString)),
+ this, SLOT(certificatesAliasComboBoxActivated(QString)));
+ connect(m_ui->certificatesAliasComboBox, SIGNAL(currentIndexChanged(QString)),
+ this, SLOT(certificatesAliasComboBoxCurrentIndexChanged(QString)));
+
+ connect(m_step->buildConfiguration(), SIGNAL(buildTypeChanged()),
+ this, SLOT(updateSigningWarning()));
+
+ updateSigningWarning();
+ QtSupport::BaseQtVersion *qt = QtSupport::QtKitInformation::qtVersion(step->target()->kit());
+ m_ui->temporaryQtOption->setVisible(qt->qtVersion() >= QtSupport::QtVersionNumber(5, 4, 0));
+}
+
+AndroidBuildApkWidget::~AndroidBuildApkWidget()
+{
+ delete m_ui;
+}
+
+QString AndroidBuildApkWidget::displayName() const
+{
+ return tr("<b>Build Android APK</b>");
+}
+
+QString AndroidBuildApkWidget::summaryText() const
+{
+ return displayName();
+}
+
+void AndroidBuildApkWidget::setTargetSdk(const QString &sdk)
+{
+ m_step->setBuildTargetSdk(sdk);
+}
+
+void AndroidBuildApkWidget::setMinistro()
+{
+ m_step->setDeployAction(AndroidBuildApkStep::MinistroDeployment);
+}
+
+void AndroidBuildApkWidget::setDeployLocalQtLibs()
+{
+ m_step->setDeployAction(AndroidBuildApkStep::DebugDeployment);
+}
+
+void AndroidBuildApkWidget::setBundleQtLibs()
+{
+ m_step->setDeployAction(AndroidBuildApkStep::BundleLibrariesDeployment);
+}
+
+void AndroidBuildApkWidget::signPackageCheckBoxToggled(bool checked)
+{
+ m_ui->certificatesAliasComboBox->setEnabled(checked);
+ m_step->setSignPackage(checked);
+ updateSigningWarning();
+ if (!checked)
+ return;
+ if (!m_step->keystorePath().isEmpty())
+ setCertificates();
+}
+
+void AndroidBuildApkWidget::createKeyStore()
+{
+ AndroidCreateKeystoreCertificate d;
+ if (d.exec() != QDialog::Accepted)
+ return;
+ m_ui->KeystoreLocationPathChooser->setPath(d.keystoreFilePath().toUserOutput());
+ m_step->setKeystorePath(d.keystoreFilePath());
+ m_step->setKeystorePassword(d.keystorePassword());
+ m_step->setCertificateAlias(d.certificateAlias());
+ m_step->setCertificatePassword(d.certificatePassword());
+ setCertificates();
+}
+
+void AndroidBuildApkWidget::setCertificates()
+{
+ QAbstractItemModel *certificates = m_step->keystoreCertificates();
+ m_ui->signPackageCheckBox->setChecked(certificates);
+ m_ui->certificatesAliasComboBox->setModel(certificates);
+}
+
+void AndroidBuildApkWidget::updateKeyStorePath(const QString &path)
+{
+ Utils::FileName file = Utils::FileName::fromString(path);
+ m_step->setKeystorePath(file);
+ m_ui->signPackageCheckBox->setChecked(!file.isEmpty());
+ if (!file.isEmpty())
+ setCertificates();
+}
+
+void AndroidBuildApkWidget::certificatesAliasComboBoxActivated(const QString &alias)
+{
+ if (alias.length())
+ m_step->setCertificateAlias(alias);
+}
+
+void AndroidBuildApkWidget::certificatesAliasComboBoxCurrentIndexChanged(const QString &alias)
+{
+ if (alias.length())
+ m_step->setCertificateAlias(alias);
+}
+
+void AndroidBuildApkWidget::openPackageLocationCheckBoxToggled(bool checked)
+{
+ m_step->setOpenPackageLocation(checked);
+}
+
+void AndroidBuildApkWidget::verboseOutputCheckBoxToggled(bool checked)
+{
+ m_step->setVerboseOutput(checked);
+}
+
+void AndroidBuildApkWidget::updateSigningWarning()
+{
+ bool debug = m_step->buildConfiguration()->buildType() == ProjectExplorer::BuildConfiguration::Debug;
+ if (m_step->signPackage() && debug) {
+ m_ui->signingDebugWarningIcon->setVisible(true);
+ m_ui->signingDebugWarningLabel->setVisible(true);
+ } else {
+ m_ui->signingDebugWarningIcon->setVisible(false);
+ m_ui->signingDebugWarningLabel->setVisible(false);
+ }
+}
+
diff --git a/src/plugins/android/androidbuildapkwidget.h b/src/plugins/android/androidbuildapkwidget.h
new file mode 100644
index 0000000000..5a7f896df7
--- /dev/null
+++ b/src/plugins/android/androidbuildapkwidget.h
@@ -0,0 +1,82 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 BogDan Vatra <bog_dan_ro@yahoo.com>
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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.
+**
+****************************************************************************/
+
+#ifndef ANDROIDBUILDAPKWIDGET_H
+#define ANDROIDBUILDAPKWIDGET_H
+
+#include "android_global.h"
+
+#include <projectexplorer/buildstep.h>
+
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+namespace Ui { class AndroidBuildApkWidget; }
+QT_END_NAMESPACE
+
+namespace QmakeProjectManager { class QmakeBuildConfiguration; }
+
+namespace Android {
+class AndroidBuildApkStep;
+
+class ANDROID_EXPORT AndroidBuildApkWidget : public ProjectExplorer::BuildStepConfigWidget
+{
+ Q_OBJECT
+
+public:
+ AndroidBuildApkWidget(AndroidBuildApkStep *step);
+ ~AndroidBuildApkWidget();
+
+private slots:
+ void setTargetSdk(const QString &sdk);
+ void setMinistro();
+ void setDeployLocalQtLibs();
+ void setBundleQtLibs();
+ void createKeyStore();
+ void certificatesAliasComboBoxCurrentIndexChanged(const QString &alias);
+ void certificatesAliasComboBoxActivated(const QString &alias);
+ void updateSigningWarning();
+ void openPackageLocationCheckBoxToggled(bool checked);
+ void verboseOutputCheckBoxToggled(bool checked);
+ void updateKeyStorePath(const QString &path);
+ void signPackageCheckBoxToggled(bool checked);
+
+private:
+ virtual QString summaryText() const;
+ virtual QString displayName() const;
+ void setCertificates();
+
+ Ui::AndroidBuildApkWidget *m_ui;
+ AndroidBuildApkStep *m_step;
+};
+
+}
+
+#endif // ANDROIDBUILDAPKWIDGET_H
diff --git a/src/plugins/android/androidbuildapkwidget.ui b/src/plugins/android/androidbuildapkwidget.ui
new file mode 100644
index 0000000000..f663669028
--- /dev/null
+++ b/src/plugins/android/androidbuildapkwidget.ui
@@ -0,0 +1,228 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AndroidBuildApkWidget</class>
+ <widget class="QWidget" name="AndroidBuildApkWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>819</width>
+ <height>390</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="1" column="0" colspan="2">
+ <widget class="QGroupBox" name="signPackage">
+ <property name="title">
+ <string>Sign package</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="KeystoreLocationLabel">
+ <property name="text">
+ <string>Keystore:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Utils::PathChooser" name="KeystoreLocationPathChooser" native="true"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="KeystoreCreatePushButton">
+ <property name="text">
+ <string>Create...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QCheckBox" name="signPackageCheckBox">
+ <property name="text">
+ <string>Sign package</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLabel" name="signingDebugWarningIcon">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="../coreplugin/core.qrc">:/core/images/warning.png</pixmap>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="signingDebugWarningLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Signing a debug package</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="KeystoreLocationLabel_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Certificate alias:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="certificatesAliasComboBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="2">
+ <widget class="QGroupBox" name="application">
+ <property name="title">
+ <string>Application</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <widget class="QLabel" name="targetSDKLabel">
+ <property name="text">
+ <string>Android build SDK:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="targetSDKComboBox"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QGroupBox" name="advancedActions">
+ <property name="title">
+ <string>Advanced Actions</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="verboseOutputCheckBox">
+ <property name="text">
+ <string>Verbose output</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="openPackageLocationCheckBox">
+ <property name="text">
+ <string>Open package location after build</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QGroupBox" name="qtDeployment">
+ <property name="title">
+ <string>Qt Deployment</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QRadioButton" name="ministroOption">
+ <property name="toolTip">
+ <string>Uses the external Ministro application to download and maintain Qt libraries.</string>
+ </property>
+ <property name="text">
+ <string>Use Ministro service to install Qt</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="bundleQtOption">
+ <property name="toolTip">
+ <string>Creates a standalone APK.</string>
+ </property>
+ <property name="text">
+ <string>Bundle Qt libraries in APK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="temporaryQtOption">
+ <property name="toolTip">
+ <string>Pushes local Qt libraries to device. You must have Qt libraries compiled for that platform.
+The APK will not be usable on any other device.</string>
+ </property>
+ <property name="text">
+ <string>Deploy local Qt libraries to temporary directory</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Utils::PathChooser</class>
+ <extends>QWidget</extends>
+ <header location="global">utils/pathchooser.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources>
+ <include location="../coreplugin/core.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp
index 84416075f4..7fa5c938a9 100644
--- a/src/plugins/android/androidconfigurations.cpp
+++ b/src/plugins/android/androidconfigurations.cpp
@@ -73,7 +73,7 @@ using namespace ProjectExplorer;
using namespace Utils;
namespace Android {
-namespace Internal {
+using namespace Internal;
namespace {
const QLatin1String SettingsGroup("AndroidConfigurations");
@@ -343,6 +343,11 @@ QStringList AndroidConfig::apiLevelNamesFor(const QList<SdkPlatform> &platforms)
return results;
}
+QString AndroidConfig::apiLevelNameFor(const SdkPlatform &platform)
+{
+ return QLatin1String("android-") + QString::number(platform.apiLevel);
+}
+
QList<SdkPlatform> AndroidConfig::sdkTargets(int minApiLevel) const
{
updateAvailableSdkPlatforms();
@@ -1294,5 +1299,4 @@ void AndroidConfigurations::updateAndroidDevice()
AndroidConfigurations *AndroidConfigurations::m_instance = 0;
-} // namespace Internal
} // namespace Android
diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h
index 98a1474669..3b28c80f79 100644
--- a/src/plugins/android/androidconfigurations.h
+++ b/src/plugins/android/androidconfigurations.h
@@ -30,6 +30,8 @@
#ifndef ANDROIDCONFIGURATIONS_H
#define ANDROIDCONFIGURATIONS_H
+#include "android_global.h"
+
#include <QObject>
#include <QString>
#include <QStringList>
@@ -37,7 +39,9 @@
#include <QHash>
#include <QMap>
#include <QFutureInterface>
+
#include <projectexplorer/abi.h>
+
#include <utils/fileutils.h>
#include <utils/environment.h>
@@ -49,7 +53,6 @@ namespace ProjectExplorer { class Project; }
namespace Android {
class AndroidPlugin;
-namespace Internal {
struct AndroidDeviceInfo
{
@@ -76,7 +79,7 @@ public:
QStringList abis;
};
-class AndroidConfig
+class ANDROID_EXPORT AndroidConfig
{
public:
AndroidConfig();
@@ -85,6 +88,7 @@ public:
void save(QSettings &settings) const;
static QStringList apiLevelNamesFor(const QList<SdkPlatform> &platforms);
+ static QString apiLevelNameFor(const SdkPlatform &platform);
QList<SdkPlatform> sdkTargets(int minApiLevel = 0) const;
Utils::FileName sdkLocation() const;
@@ -192,7 +196,7 @@ private:
mutable QHash<QString, QString> m_serialNumberToDeviceName;
};
-class AndroidConfigurations : public QObject
+class ANDROID_EXPORT AndroidConfigurations : public QObject
{
friend class Android::AndroidPlugin;
Q_OBJECT
@@ -225,7 +229,6 @@ private:
QMap<ProjectExplorer::Project *, QMap<QString, QString> > m_defaultDeviceForAbi;
};
-} // namespace Internal
} // namespace Android
#endif // ANDROIDCONFIGURATIONS_H
diff --git a/src/plugins/android/androidconstants.h b/src/plugins/android/androidconstants.h
index f84e18f9b8..d05555661e 100644
--- a/src/plugins/android/androidconstants.h
+++ b/src/plugins/android/androidconstants.h
@@ -73,6 +73,11 @@ const char JAVA_MIMETYPE[] = "text/x-java";
const char WIZARD_JAVA[] = "Wizard.Java";
const char JAVA_WIZARD_CATEGORY[] = "U.Java";
const char JAVA_DISPLAY_CATEGORY[] = "Java";
+const char ANDROID_ARCHITECTURE[] = "Android.Architecture";
+const char ANDROID_DEPLOY_SETTINGS_FILE[] = "AndroidDeploySettingsFile";
+const char ANDROID_PACKAGE_SOURCE_DIR[] = "AndroidPackageSourceDir";
+const char ANDROID_EXTRA_LIBS[] = "AndroidExtraLibs";
+
} // namespace Constants;
} // namespace Android
diff --git a/src/plugins/android/androiddebugsupport.h b/src/plugins/android/androiddebugsupport.h
index 5cea83a0db..ef705f644a 100644
--- a/src/plugins/android/androiddebugsupport.h
+++ b/src/plugins/android/androiddebugsupport.h
@@ -42,7 +42,6 @@ namespace Android {
class AndroidRunConfiguration;
namespace Internal {
-
class AndroidRunner;
class AndroidDebugSupport : public AndroidRunSupport
diff --git a/src/plugins/android/androiddeployconfiguration.cpp b/src/plugins/android/androiddeployconfiguration.cpp
index f90c33e214..177413f4ce 100644
--- a/src/plugins/android/androiddeployconfiguration.cpp
+++ b/src/plugins/android/androiddeployconfiguration.cpp
@@ -29,15 +29,15 @@
#include "androiddeployconfiguration.h"
#include "androidconstants.h"
-#include "androidpackageinstallationstep.h"
#include "androiddeployqtstep.h"
#include "androidmanager.h"
+#include "androidqtsupport.h"
#include <projectexplorer/buildsteplist.h>
+#include <projectexplorer/project.h>
#include <projectexplorer/target.h>
#include <projectexplorer/toolchain.h>
-#include <qmakeprojectmanager/qmakeproject.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtsupportconstants.h>
@@ -73,9 +73,7 @@ bool AndroidDeployConfigurationFactory::canCreate(Target *parent, Core::Id id) c
DeployConfiguration *AndroidDeployConfigurationFactory::create(Target *parent, Core::Id id)
{
AndroidDeployConfiguration *dc = new AndroidDeployConfiguration(parent, id);
-
- dc->stepList()->insertStep(0, new AndroidPackageInstallationStep(AndroidPackageInstallationStep::BuildDirectory, dc->stepList()));
- dc->stepList()->insertStep(1, new AndroidDeployQtStep(dc->stepList()));
+ dc->stepList()->insertStep(0, new AndroidDeployQtStep(dc->stepList()));
return dc;
}
@@ -114,9 +112,6 @@ DeployConfiguration *AndroidDeployConfigurationFactory::clone(Target *parent, De
QList<Core::Id> AndroidDeployConfigurationFactory::availableCreationIds(Target *parent) const
{
QList<Core::Id> ids;
- if (!qobject_cast<QmakeProjectManager::QmakeProject *>(parent->project()))
- return ids;
-
if (!parent->project()->supportsKit(parent->kit()))
return ids;
diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp
index 6263d6292c..cc3ec1a596 100644
--- a/src/plugins/android/androiddeployqtstep.cpp
+++ b/src/plugins/android/androiddeployqtstep.cpp
@@ -30,38 +30,43 @@
#include "androiddeployqtstep.h"
#include "androiddeployqtwidget.h"
+#include "androidqtsupport.h"
#include "certificatesmodel.h"
#include "javaparser.h"
#include "androidmanager.h"
#include "androidconstants.h"
-#include <utils/qtcassert.h>
-#include <utils/qtcprocess.h>
#include <coreplugin/fileutils.h>
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
+
+#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/projectexplorerconstants.h>
-#include <projectexplorer/target.h>
#include <projectexplorer/project.h>
+#include <projectexplorer/target.h>
+
#include <qtsupport/qtkitinformation.h>
-#include <qmakeprojectmanager/qmakebuildconfiguration.h>
-#include <qmakeprojectmanager/qmakeproject.h>
-#include <qmakeprojectmanager/qmakenodes.h>
+
+#include <utils/qtcassert.h>
+#include <utils/qtcprocess.h>
+
#include <QInputDialog>
#include <QMessageBox>
+
using namespace Android;
using namespace Android::Internal;
-const QLatin1String DeployActionKey("Qt4ProjectManager.AndroidDeployQtStep.DeployQtAction");
+const QLatin1String UninstallPreviousPackageKey("UninstallPreviousPackage");
const QLatin1String KeystoreLocationKey("KeystoreLocation");
const QLatin1String SignPackageKey("SignPackage");
const QLatin1String BuildTargetSdkKey("BuildTargetSdk");
const QLatin1String VerboseOutputKey("VerboseOutput");
const QLatin1String InputFile("InputFile");
const QLatin1String ProFilePathForInputFile("ProFilePathForInputFile");
+const QLatin1String InstallFailedInconsistentCertificatesString("INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES");
const Core::Id AndroidDeployQtStep::Id("Qt4ProjectManager.AndroidDeployQtStep");
//////////////////
@@ -149,20 +154,12 @@ AndroidDeployQtStep::AndroidDeployQtStep(ProjectExplorer::BuildStepList *parent,
void AndroidDeployQtStep::ctor()
{
+ m_uninstallPreviousPackage = false;
+ m_uninstallPreviousPackageTemp = false;
+ m_uninstallPreviousPackageRun = false;
+
//: AndroidDeployQtStep default display name
setDefaultDisplayName(tr("Deploy to Android device"));
- m_deployAction = BundleLibrariesDeployment;
- m_signPackage = false;
- m_openPackageLocation = false;
- m_verbose = false;
-
- // will be overwriten by settings if the user choose something different
- SdkPlatform sdk = AndroidConfigurations::currentConfig().highestAndroidSdk();
- if (sdk.apiLevel > 0)
- m_buildTargetSdk = QLatin1String("android-") + QString::number(sdk.apiLevel);
-
- connect(project(), SIGNAL(proFilesEvaluated()),
- this, SLOT(updateInputFile()));
}
bool AndroidDeployQtStep::init()
@@ -188,109 +185,34 @@ bool AndroidDeployQtStep::init()
m_avdName.clear();
m_serialNumber = info.serialNumber;
}
+ AndroidManager::setDeviceSerialNumber(target(), m_serialNumber);
- QmakeProjectManager::QmakeBuildConfiguration *bc
- = static_cast<QmakeProjectManager::QmakeBuildConfiguration *>(target()->activeBuildConfiguration());
-
- if (m_signPackage) {
- // check keystore and certificate passwords
- while (!AndroidManager::checkKeystorePassword(m_keystorePath.toString(), m_keystorePasswd)) {
- if (!keystorePassword())
- return false; // user canceled
- }
-
- while (!AndroidManager::checkCertificatePassword(m_keystorePath.toString(), m_keystorePasswd, m_certificateAlias, m_certificatePasswd)) {
- if (!certificatePassword())
- return false; // user canceled
- }
-
-
- if ((bc->qmakeBuildConfiguration() & QtSupport::BaseQtVersion::DebugBuild))
- emit addOutput(tr("Warning: Signing a debug package."), BuildStep::ErrorMessageOutput);
- }
+ ProjectExplorer::BuildConfiguration *bc = target()->activeBuildConfiguration();
QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit());
if (!version)
return false;
- QmakeProjectManager::QmakeProject *pro = static_cast<QmakeProjectManager::QmakeProject *>(project());
- JavaParser *parser = new JavaParser;
- parser->setProjectFileList(pro->files(ProjectExplorer::Project::AllFiles));
- setOutputParser(parser);
-
- QString command = version->qmakeProperty("QT_HOST_BINS");
- if (!command.endsWith(QLatin1Char('/')))
- command += QLatin1Char('/');
- command += Utils::HostOsInfo::withExecutableSuffix(QLatin1String("androiddeployqt"));
-
- QString deploymentMethod;
- if (m_deployAction == MinistroDeployment)
- deploymentMethod = QLatin1String("ministro");
- else if (m_deployAction == DebugDeployment)
- deploymentMethod = QLatin1String("debug");
- else if (m_deployAction == BundleLibrariesDeployment)
- deploymentMethod = QLatin1String("bundled");
-
- QString outputDir = bc->buildDirectory().appendPath(QLatin1String(Constants::ANDROID_BUILDDIRECTORY)).toString();
- const QmakeProjectManager::QmakeProFileNode *node = pro->rootQmakeProjectNode()->findProFileFor(m_proFilePathForInputFile);
- if (!node) { // should never happen
- emit addOutput(tr("Internal Error: Could not find .pro file."), BuildStep::ErrorMessageOutput);
- return false;
- }
-
- QString inputFile = node->singleVariableValue(QmakeProjectManager::AndroidDeploySettingsFile);
- if (inputFile.isEmpty()) { // should never happen
- emit addOutput(tr("Internal Error: Unknown Android deployment JSON file location."), BuildStep::ErrorMessageOutput);
- return false;
- }
-
- QStringList arguments;
- arguments << QLatin1String("--input")
- << inputFile
- << QLatin1String("--output")
- << outputDir
- << QLatin1String("--deployment")
- << deploymentMethod
- << QLatin1String("--install")
- << QLatin1String("--ant")
- << AndroidConfigurations::currentConfig().antToolPath().toString()
- << QLatin1String("--android-platform")
- << m_buildTargetSdk
- << QLatin1String("--jdk")
- << AndroidConfigurations::currentConfig().openJDKLocation().toString();
-
- parser->setSourceDirectory(Utils::FileName::fromString(node->singleVariableValue(QmakeProjectManager::AndroidPackageSourceDir)));
- parser->setBuildDirectory(Utils::FileName::fromString(outputDir));
-
- if (m_verbose)
- arguments << QLatin1String("--verbose");
- if (m_avdName.isEmpty())
- arguments << QLatin1String("--device")
- << info.serialNumber;
-
- if (m_signPackage) {
- arguments << QLatin1String("--sign")
- << m_keystorePath.toString()
- << m_certificateAlias
- << QLatin1String("--storepass")
- << m_keystorePasswd;
- if (!m_certificatePasswd.isEmpty())
- arguments << QLatin1String("--keypass")
- << m_certificatePasswd;
+ m_uninstallPreviousPackageRun = m_uninstallPreviousPackage || m_uninstallPreviousPackageTemp;
+ m_uninstallPreviousPackageTemp = false;
+ if (m_uninstallPreviousPackageRun) {
+ m_packageName = AndroidManager::packageName(target());
+ if (m_packageName.isEmpty()){
+ emit addOutput(tr("Cannot find the package name."), ErrorOutput);
+ return false;
+ }
}
ProjectExplorer::ProcessParameters *pp = processParameters();
+ pp->setCommand(AndroidConfigurations::currentConfig().adbToolPath().toString());
pp->setMacroExpander(bc->macroExpander());
pp->setWorkingDirectory(bc->buildDirectory().toString());
Utils::Environment env = bc->environment();
pp->setEnvironment(env);
- pp->setCommand(command);
- pp->setArguments(Utils::QtcProcess::joinArgs(arguments));
- pp->resolveAll();
+ m_apkPath = AndroidManager::androidQtSupport(target())->apkPath(target(), AndroidManager::signPackage(target())
+ ? AndroidQtSupport::ReleaseBuildSigned
+ : AndroidQtSupport::DebugBuild).toString();
- m_openPackageLocationForRun = m_openPackageLocation;
- m_apkPath = AndroidManager::apkPath(target(), m_signPackage ? AndroidManager::ReleaseBuildSigned
- : AndroidManager::DebugBuild).toString();
m_buildDirectory = bc->buildDirectory().toString();
bool result = AbstractProcessStep::init();
@@ -304,6 +226,7 @@ bool AndroidDeployQtStep::init()
void AndroidDeployQtStep::run(QFutureInterface<bool> &fi)
{
+ m_installOk = true;
if (!m_avdName.isEmpty()) {
QString serialNumber = AndroidConfigurations::currentConfig().waitForAvd(m_deviceAPILevel, m_targetArch, fi);
if (serialNumber.isEmpty()) {
@@ -312,12 +235,27 @@ void AndroidDeployQtStep::run(QFutureInterface<bool> &fi)
return;
}
m_serialNumber = serialNumber;
- QString args = processParameters()->arguments();
- Utils::QtcProcess::addArg(&args, QLatin1String("--device"));
- Utils::QtcProcess::addArg(&args, serialNumber);
- processParameters()->setArguments(args);
+ AndroidManager::setDeviceSerialNumber(target(), serialNumber);
+ }
+
+ if (m_uninstallPreviousPackageRun) {
+ emit addOutput(tr("Uninstall previous package %1.").arg(m_packageName), MessageOutput);
+ runCommand(AndroidConfigurations::currentConfig().adbToolPath().toString(),
+ AndroidDeviceInfo::adbSelector(m_serialNumber)
+ << QLatin1String("uninstall") << m_packageName);
}
+ ProjectExplorer::ProcessParameters *pp = processParameters();
+ QString args;
+ for (const QString arg : AndroidDeviceInfo::adbSelector(m_serialNumber))
+ Utils::QtcProcess::addArg(&args, arg);
+
+ Utils::QtcProcess::addArg(&args, QLatin1String("install"));
+ Utils::QtcProcess::addArg(&args, QLatin1String("-r"));
+ Utils::QtcProcess::addArg(&args, m_apkPath);
+ pp->setArguments(args);
+ pp->resolveAll();
+
AbstractProcessStep::run(fi);
emit addOutput(tr("Pulling files necessary for debugging."), MessageOutput);
@@ -334,17 +272,17 @@ void AndroidDeployQtStep::run(QFutureInterface<bool> &fi)
void AndroidDeployQtStep::runCommand(const QString &program, const QStringList &arguments)
{
QProcess buildProc;
- emit addOutput(tr("Package deploy: Running command '%1 %2'.").arg(program).arg(arguments.join(QLatin1String(" "))), BuildStep::MessageOutput);
+ emit addOutput(tr("Package deploy: Running command \"%1 %2\".").arg(program).arg(arguments.join(QLatin1String(" "))), BuildStep::MessageOutput);
buildProc.start(program, arguments);
if (!buildProc.waitForStarted()) {
- emit addOutput(tr("Packaging error: Could not start command '%1 %2'. Reason: %3")
+ emit addOutput(tr("Packaging error: Could not start command \"%1 %2\". Reason: %3")
.arg(program).arg(arguments.join(QLatin1String(" "))).arg(buildProc.errorString()), BuildStep::ErrorMessageOutput);
return;
}
if (!buildProc.waitForFinished(2 * 60 * 1000)
|| buildProc.error() != QProcess::UnknownError
|| buildProc.exitCode() != 0) {
- QString mainMessage = tr("Packaging Error: Command '%1 %2' failed.")
+ QString mainMessage = tr("Packaging Error: Command \"%1 %2\" failed.")
.arg(program).arg(arguments.join(QLatin1String(" ")));
if (buildProc.error() != QProcess::UnknownError)
mainMessage += QLatin1Char(' ') + tr("Reason: %1").arg(buildProc.errorString());
@@ -354,148 +292,55 @@ void AndroidDeployQtStep::runCommand(const QString &program, const QStringList &
}
}
-void AndroidDeployQtStep::updateInputFile()
+ProjectExplorer::BuildStepConfigWidget *AndroidDeployQtStep::createConfigWidget()
{
- QmakeProjectManager::QmakeProject *pro = static_cast<QmakeProjectManager::QmakeProject *>(project());
- QList<QmakeProjectManager::QmakeProFileNode *> nodes = pro->applicationProFiles();
-
- const QmakeProjectManager::QmakeProFileNode *node = pro->rootQmakeProjectNode()->findProFileFor(m_proFilePathForInputFile);
- if (!nodes.contains(const_cast<QmakeProjectManager::QmakeProFileNode *>(node))) {
- if (!nodes.isEmpty())
- m_proFilePathForInputFile = nodes.first()->path();
- else
- m_proFilePathForInputFile.clear();
- }
-
- emit inputFileChanged();
+ return new AndroidDeployQtWidget(this);
}
-void AndroidDeployQtStep::showInGraphicalShell()
+void AndroidDeployQtStep::stdOutput(const QString &line)
{
- Core::FileUtils::showInGraphicalShell(Core::ICore::instance()->mainWindow(), m_apkPath);
+ if (line.contains(InstallFailedInconsistentCertificatesString))
+ m_installOk = false;
+ AbstractProcessStep::stdOutput(line);
}
-ProjectExplorer::BuildStepConfigWidget *AndroidDeployQtStep::createConfigWidget()
+void AndroidDeployQtStep::stdError(const QString &line)
{
- return new AndroidDeployQtWidget(this);
+ if (line.contains(InstallFailedInconsistentCertificatesString))
+ m_installOk = false;
+ AbstractProcessStep::stdError(line);
}
-void AndroidDeployQtStep::processFinished(int exitCode, QProcess::ExitStatus status)
+bool AndroidDeployQtStep::processSucceeded(int exitCode, QProcess::ExitStatus status)
{
- AbstractProcessStep::processFinished(exitCode, status);
- if (m_openPackageLocationForRun && status == QProcess::NormalExit && exitCode == 0)
- QMetaObject::invokeMethod(this, "showInGraphicalShell", Qt::QueuedConnection);
+ if (!m_installOk && !m_uninstallPreviousPackageRun &&
+ QMessageBox::critical(0, tr("Install failed"),
+ tr("Another application with the same package id but signed with "
+ "different ceritificate already exists.\n"
+ "Do you want to install the existing package next time?"),
+ QMessageBox::Yes, QMessageBox::No)
+ == QMessageBox::Yes) {
+ m_uninstallPreviousPackageTemp = true;
+ }
+ return m_installOk && AbstractProcessStep::processSucceeded(exitCode, status);
}
bool AndroidDeployQtStep::fromMap(const QVariantMap &map)
{
- m_deployAction = AndroidDeployQtAction(map.value(QLatin1String(DeployActionKey),
- BundleLibrariesDeployment).toInt());
- m_keystorePath = Utils::FileName::fromString(map.value(KeystoreLocationKey).toString());
- m_signPackage = false; // don't restore this
- m_buildTargetSdk = map.value(BuildTargetSdkKey).toString();
- m_verbose = map.value(VerboseOutputKey).toBool();
- m_proFilePathForInputFile = map.value(ProFilePathForInputFile).toString();
+ m_uninstallPreviousPackage = map.value(UninstallPreviousPackageKey, false).toBool();
return ProjectExplorer::BuildStep::fromMap(map);
}
QVariantMap AndroidDeployQtStep::toMap() const
{
QVariantMap map = ProjectExplorer::BuildStep::toMap();
- map.insert(QLatin1String(DeployActionKey), m_deployAction);
- map.insert(KeystoreLocationKey, m_keystorePath.toString());
- map.insert(SignPackageKey, m_signPackage);
- map.insert(BuildTargetSdkKey, m_buildTargetSdk);
- map.insert(VerboseOutputKey, m_verbose);
- map.insert(ProFilePathForInputFile, m_proFilePathForInputFile);
+ map.insert(UninstallPreviousPackageKey, m_uninstallPreviousPackage);
return map;
}
-void AndroidDeployQtStep::setBuildTargetSdk(const QString &sdk)
-{
- m_buildTargetSdk = sdk;
-}
-
-QString AndroidDeployQtStep::buildTargetSdk() const
-{
- return m_buildTargetSdk;
-}
-
-Utils::FileName AndroidDeployQtStep::keystorePath()
-{
- return m_keystorePath;
-}
-
-AndroidDeployQtStep::AndroidDeployQtAction AndroidDeployQtStep::deployAction() const
-{
- return m_deployAction;
-}
-
-void AndroidDeployQtStep::setDeployAction(AndroidDeployQtStep::AndroidDeployQtAction deploy)
-{
- m_deployAction = deploy;
-}
-
-void AndroidDeployQtStep::setKeystorePath(const Utils::FileName &path)
-{
- m_keystorePath = path;
- m_certificatePasswd.clear();
- m_keystorePasswd.clear();
-}
-
-void AndroidDeployQtStep::setKeystorePassword(const QString &pwd)
-{
- m_keystorePasswd = pwd;
-}
-
-void AndroidDeployQtStep::setCertificateAlias(const QString &alias)
-{
- m_certificateAlias = alias;
-}
-
-void AndroidDeployQtStep::setCertificatePassword(const QString &pwd)
-{
- m_certificatePasswd = pwd;
-}
-
-bool AndroidDeployQtStep::signPackage() const
-{
- return m_signPackage;
-}
-
-void AndroidDeployQtStep::setSignPackage(bool b)
-{
- m_signPackage = b;
-}
-
-QString AndroidDeployQtStep::deviceSerialNumber()
-{
- return m_serialNumber;
-}
-
-bool AndroidDeployQtStep::openPackageLocation() const
-{
- return m_openPackageLocation;
-}
-
-void AndroidDeployQtStep::setOpenPackageLocation(bool open)
+void AndroidDeployQtStep::setUninstallPreviousPackage(bool uninstall)
{
- m_openPackageLocation = open;
-}
-
-void AndroidDeployQtStep::setVerboseOutput(bool verbose)
-{
- m_verbose = verbose;
-}
-
-QString AndroidDeployQtStep::proFilePathForInputFile() const
-{
- return m_proFilePathForInputFile;
-}
-
-void AndroidDeployQtStep::setProFilePathForInputFile(const QString &path)
-{
- m_proFilePathForInputFile = path;
+ m_uninstallPreviousPackage = uninstall;
}
bool AndroidDeployQtStep::runInGuiThread() const
@@ -503,69 +348,7 @@ bool AndroidDeployQtStep::runInGuiThread() const
return true;
}
-bool AndroidDeployQtStep::verboseOutput() const
-{
- return m_verbose;
-}
-
-// Note this functions is duplicated between AndroidDeployStep and AndroidDeployQtStep
-// since it does modify the stored password in AndroidDeployQtStep it's not easily
-// extractable. The situation will clean itself up once AndroidDeployStep is no longer
-// necessary
-QAbstractItemModel *AndroidDeployQtStep::keystoreCertificates()
+bool AndroidDeployQtStep::uninstallPreviousPackage()
{
- QString rawCerts;
- QProcess keytoolProc;
- while (!rawCerts.length() || !m_keystorePasswd.length()) {
- QStringList params;
- params << QLatin1String("-list") << QLatin1String("-v") << QLatin1String("-keystore") << m_keystorePath.toUserOutput() << QLatin1String("-storepass");
- if (!m_keystorePasswd.length())
- keystorePassword();
- if (!m_keystorePasswd.length())
- return 0;
- params << m_keystorePasswd;
- params << QLatin1String("-J-Duser.language=en");
- keytoolProc.start(AndroidConfigurations::currentConfig().keytoolPath().toString(), params);
- if (!keytoolProc.waitForStarted() || !keytoolProc.waitForFinished()) {
- QMessageBox::critical(0, tr("Error"),
- tr("Failed to run keytool."));
- return 0;
- }
-
- if (keytoolProc.exitCode()) {
- QMessageBox::critical(0, tr("Error"),
- tr("Invalid password."));
- m_keystorePasswd.clear();
- }
- rawCerts = QString::fromLatin1(keytoolProc.readAllStandardOutput());
- }
- return new CertificatesModel(rawCerts, this);
-}
-
-bool AndroidDeployQtStep::keystorePassword()
-{
- m_keystorePasswd.clear();
- bool ok;
- QString text = QInputDialog::getText(0, tr("Keystore"),
- tr("Keystore password:"), QLineEdit::Password,
- QString(), &ok);
- if (ok && !text.isEmpty()) {
- m_keystorePasswd = text;
- return true;
- }
- return false;
-}
-
-bool AndroidDeployQtStep::certificatePassword()
-{
- m_certificatePasswd.clear();
- bool ok;
- QString text = QInputDialog::getText(0, tr("Certificate"),
- tr("Certificate password (%1):").arg(m_certificateAlias), QLineEdit::Password,
- QString(), &ok);
- if (ok && !text.isEmpty()) {
- m_certificatePasswd = text;
- return true;
- }
- return false;
+ return m_uninstallPreviousPackage;
}
diff --git a/src/plugins/android/androiddeployqtstep.h b/src/plugins/android/androiddeployqtstep.h
index 01745ccb5c..68f94bd552 100644
--- a/src/plugins/android/androiddeployqtstep.h
+++ b/src/plugins/android/androiddeployqtstep.h
@@ -71,91 +71,46 @@ class AndroidDeployQtStep : public ProjectExplorer::AbstractProcessStep
public:
AndroidDeployQtStep(ProjectExplorer::BuildStepList *bc);
- enum AndroidDeployQtAction
- {
- MinistroDeployment, // use ministro
- DebugDeployment,
- BundleLibrariesDeployment
- };
-
bool fromMap(const QVariantMap &map);
QVariantMap toMap() const;
- AndroidDeployQtStep::AndroidDeployQtAction deployAction() const;
- QString deviceSerialNumber();
-
- void setBuildTargetSdk(const QString &sdk);
- QString buildTargetSdk() const;
-
- // signing
- Utils::FileName keystorePath();
- void setKeystorePath(const Utils::FileName &path);
- void setKeystorePassword(const QString &pwd);
- void setCertificateAlias(const QString &alias);
- void setCertificatePassword(const QString &pwd);
-
- QAbstractItemModel *keystoreCertificates();
- bool signPackage() const;
- void setSignPackage(bool b);
-
- bool openPackageLocation() const;
- void setOpenPackageLocation(bool open);
- bool verboseOutput() const;
- void setVerboseOutput(bool verbose);
-
- QString proFilePathForInputFile() const;
- void setProFilePathForInputFile(const QString &path);
-
bool runInGuiThread() const;
-signals:
- // also on purpose emitted if the possible values of this changed
- void inputFileChanged();
+ bool uninstallPreviousPackage();
public slots:
- void setDeployAction(AndroidDeployQtAction deploy); // slot?
-
-private slots:
- void showInGraphicalShell();
+ void setUninstallPreviousPackage(bool uninstall);
- void updateInputFile();
private:
AndroidDeployQtStep(ProjectExplorer::BuildStepList *bc,
AndroidDeployQtStep *other);
void ctor();
- bool keystorePassword();
- bool certificatePassword();
void runCommand(const QString &program, const QStringList &arguments);
bool init();
void run(QFutureInterface<bool> &fi);
ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
bool immutable() const { return true; }
- void processFinished(int exitCode, QProcess::ExitStatus status);
+ void stdOutput(const QString &line);
+ void stdError(const QString &line);
+ virtual bool processSucceeded(int exitCode, QProcess::ExitStatus status);
- QString m_buildTargetSdk;
+ QString m_packageName;
QString m_serialNumber;
- AndroidDeployQtAction m_deployAction;
- bool m_signPackage;
- bool m_verbose;
- bool m_openPackageLocation;
- bool m_openPackageLocationForRun;
QString m_buildDirectory;
-
- Utils::FileName m_keystorePath;
- QString m_keystorePasswd;
- QString m_certificateAlias;
- QString m_certificatePasswd;
QString m_avdName;
QString m_apkPath;
+
QString m_targetArch;
- QString m_proFilePathForInputFile;
int m_deviceAPILevel;
-
+ bool m_uninstallPreviousPackage;
+ bool m_uninstallPreviousPackageTemp;
+ bool m_uninstallPreviousPackageRun;
static const Core::Id Id;
+ bool m_installOk;
};
}
-}
+} // namespace Android
#endif // ANDROIDDEPLOYQTSTEP_H
diff --git a/src/plugins/android/androiddeployqtwidget.cpp b/src/plugins/android/androiddeployqtwidget.cpp
index b07ab8f827..11f9bf9bdb 100644
--- a/src/plugins/android/androiddeployqtwidget.cpp
+++ b/src/plugins/android/androiddeployqtwidget.cpp
@@ -31,133 +31,28 @@
#include "androiddeployqtwidget.h"
#include "ui_androiddeployqtwidget.h"
-#include "androidcreatekeystorecertificate.h"
#include "androiddeployqtstep.h"
#include "androidmanager.h"
-#include "createandroidmanifestwizard.h"
-#include "androidextralibrarylistmodel.h"
-
-#include <projectexplorer/target.h>
-#include <qmakeprojectmanager/qmakebuildconfiguration.h>
-#include <qmakeprojectmanager/qmakeproject.h>
-#include <qmakeprojectmanager/qmakenodes.h>
-#include <utils/fancylineedit.h>
-#include <utils/pathchooser.h>
#include <QFileDialog>
-#include <algorithm>
-
-
using namespace Android;
using namespace Internal;
AndroidDeployQtWidget::AndroidDeployQtWidget(AndroidDeployQtStep *step)
: ProjectExplorer::BuildStepConfigWidget(),
m_ui(new Ui::AndroidDeployQtWidget),
- m_step(step),
- m_currentBuildConfiguration(0),
- m_ignoreChange(false)
+ m_step(step)
{
m_ui->setupUi(this);
- // Target sdk combobox
- int minApiLevel = 9;
- QStringList targets = AndroidConfig::apiLevelNamesFor(AndroidConfigurations::currentConfig().sdkTargets(minApiLevel));
- m_ui->targetSDKComboBox->addItems(targets);
- m_ui->targetSDKComboBox->setCurrentIndex(targets.indexOf(step->buildTargetSdk()));
-
- // deployment option
- switch (m_step->deployAction()) {
- case AndroidDeployQtStep::MinistroDeployment:
- m_ui->ministroOption->setChecked(true);
- break;
- case AndroidDeployQtStep::DebugDeployment:
- m_ui->temporaryQtOption->setChecked(true);
- break;
- case AndroidDeployQtStep::BundleLibrariesDeployment:
- m_ui->bundleQtOption->setChecked(true);
- break;
- default:
- // can't happen
- break;
- }
-
- // signing
- m_ui->signPackageCheckBox->setChecked(m_step->signPackage());
- m_ui->KeystoreLocationPathChooser->setExpectedKind(Utils::PathChooser::File);
- m_ui->KeystoreLocationPathChooser->lineEdit()->setReadOnly(true);
- m_ui->KeystoreLocationPathChooser->setPath(m_step->keystorePath().toUserOutput());
- m_ui->KeystoreLocationPathChooser->setInitialBrowsePathBackup(QDir::homePath());
- m_ui->KeystoreLocationPathChooser->setPromptDialogFilter(tr("Keystore files (*.keystore *.jks)"));
- m_ui->KeystoreLocationPathChooser->setPromptDialogTitle(tr("Select keystore file"));
- m_ui->signingDebugWarningIcon->hide();
- m_ui->signingDebugWarningLabel->hide();
- signPackageCheckBoxToggled(m_step->signPackage());
-
- m_ui->verboseOutputCheckBox->setChecked(m_step->verboseOutput());
- m_ui->openPackageLocationCheckBox->setChecked(m_step->openPackageLocation());
-
- bool oldFiles = AndroidManager::checkForQt51Files(m_step->project()->projectDirectory());
- m_ui->oldFilesWarningIcon->setVisible(oldFiles);
- m_ui->oldFilesWarningLabel->setVisible(oldFiles);
-
- // target sdk
- connect(m_ui->targetSDKComboBox, SIGNAL(activated(QString)), SLOT(setTargetSdk(QString)));
-
- // deployment options
- connect(m_ui->ministroOption, SIGNAL(clicked()), SLOT(setMinistro()));
- connect(m_ui->temporaryQtOption, SIGNAL(clicked()), SLOT(setDeployLocalQtLibs()));
- connect(m_ui->bundleQtOption, SIGNAL(clicked()), SLOT(setBundleQtLibs()));
-
+ m_ui->uninstallPreviousPackage->setChecked(m_step->uninstallPreviousPackage());
connect(m_ui->installMinistroButton, SIGNAL(clicked()), SLOT(installMinistro()));
connect(m_ui->cleanLibsPushButton, SIGNAL(clicked()), SLOT(cleanLibsOnDevice()));
connect(m_ui->resetDefaultDevices, SIGNAL(clicked()), SLOT(resetDefaultDevices()));
- connect(m_ui->openPackageLocationCheckBox, SIGNAL(toggled(bool)),
- this, SLOT(openPackageLocationCheckBoxToggled(bool)));
- connect(m_ui->verboseOutputCheckBox, SIGNAL(toggled(bool)),
- this, SLOT(verboseOutputCheckBoxToggled(bool)));
-
- //signing
- connect(m_ui->signPackageCheckBox, SIGNAL(toggled(bool)),
- this, SLOT(signPackageCheckBoxToggled(bool)));
- connect(m_ui->KeystoreCreatePushButton, SIGNAL(clicked()),
- this, SLOT(createKeyStore()));
- connect(m_ui->KeystoreLocationPathChooser, SIGNAL(pathChanged(QString)),
- SLOT(updateKeyStorePath(QString)));
- connect(m_ui->certificatesAliasComboBox, SIGNAL(activated(QString)),
- this, SLOT(certificatesAliasComboBoxActivated(QString)));
- connect(m_ui->certificatesAliasComboBox, SIGNAL(currentIndexChanged(QString)),
- this, SLOT(certificatesAliasComboBoxCurrentIndexChanged(QString)));
+ connect(m_ui->uninstallPreviousPackage, SIGNAL(toggled(bool)),
+ m_step, SLOT(setUninstallPreviousPackage(bool)));
- activeBuildConfigurationChanged();
- connect(m_step->target(), SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
- this, SLOT(activeBuildConfigurationChanged()));
-
- connect(m_ui->inputFileComboBox, SIGNAL(currentIndexChanged(int)),
- this, SLOT(inputFileComboBoxIndexChanged()));
-
- updateInputFileUi();
- connect(m_step, SIGNAL(inputFileChanged()),
- this, SLOT(updateInputFileUi()));
-
- connect(m_ui->createAndroidManifestButton, SIGNAL(clicked()),
- this, SLOT(createManifestButton()));
-
- m_extraLibraryListModel = new AndroidExtraLibraryListModel(static_cast<QmakeProjectManager::QmakeProject *>(m_step->project()),
- this);
- m_ui->androidExtraLibsListView->setModel(m_extraLibraryListModel);
-
- connect(m_ui->androidExtraLibsListView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- this, SLOT(checkEnableRemoveButton()));
-
- connect(m_ui->addAndroidExtraLibButton, SIGNAL(clicked()), this, SLOT(addAndroidExtraLib()));
- connect(m_ui->removeAndroidExtraLibButton, SIGNAL(clicked()), this, SLOT(removeAndroidExtraLib()));
-
- connect(m_extraLibraryListModel, SIGNAL(enabledChanged(bool)),
- m_ui->additionalLibrariesGroupBox, SLOT(setEnabled(bool)));
-
- m_ui->additionalLibrariesGroupBox->setEnabled(m_extraLibraryListModel->isEnabled());
}
AndroidDeployQtWidget::~AndroidDeployQtWidget()
@@ -165,45 +60,6 @@ AndroidDeployQtWidget::~AndroidDeployQtWidget()
delete m_ui;
}
-void AndroidDeployQtWidget::createManifestButton()
-{
- CreateAndroidManifestWizard wizard(m_step->target());
- wizard.exec();
-}
-
-void AndroidDeployQtWidget::updateInputFileUi()
-{
- QmakeProjectManager::QmakeProject *project
- = static_cast<QmakeProjectManager::QmakeProject *>(m_step->project());
- QList<QmakeProjectManager::QmakeProFileNode *> nodes = project->applicationProFiles();
- int size = nodes.size();
- if (size == 0 || size == 1) {
- // there's nothing to select, e.g. before parsing
- m_ui->inputFileLabel->setVisible(false);
- m_ui->inputFileComboBox->setVisible(false);
- } else {
- m_ignoreChange = true;
- m_ui->inputFileLabel->setVisible(true);
- m_ui->inputFileComboBox->setVisible(true);
-
- m_ui->inputFileComboBox->clear();
- foreach (QmakeProjectManager::QmakeProFileNode *node, nodes)
- m_ui->inputFileComboBox->addItem(node->displayName(), node->path());
-
- int index = m_ui->inputFileComboBox->findData(m_step->proFilePathForInputFile());
- m_ui->inputFileComboBox->setCurrentIndex(index);
- m_ignoreChange = false;
- }
-}
-
-void AndroidDeployQtWidget::inputFileComboBoxIndexChanged()
-{
- if (m_ignoreChange)
- return;
- QString proFilePath = m_ui->inputFileComboBox->itemData(m_ui->inputFileComboBox->currentIndex()).toString();
- m_step->setProFilePathForInputFile(proFilePath);
-}
-
QString AndroidDeployQtWidget::displayName() const
{
return tr("<b>Deploy configurations</b>");
@@ -214,26 +70,6 @@ QString AndroidDeployQtWidget::summaryText() const
return displayName();
}
-void AndroidDeployQtWidget::setTargetSdk(const QString &sdk)
-{
- m_step->setBuildTargetSdk(sdk);
-}
-
-void AndroidDeployQtWidget::setMinistro()
-{
- m_step->setDeployAction(AndroidDeployQtStep::MinistroDeployment);
-}
-
-void AndroidDeployQtWidget::setDeployLocalQtLibs()
-{
- m_step->setDeployAction(AndroidDeployQtStep::DebugDeployment);
-}
-
-void AndroidDeployQtWidget::setBundleQtLibs()
-{
- m_step->setDeployAction(AndroidDeployQtStep::BundleLibrariesDeployment);
-}
-
void AndroidDeployQtWidget::installMinistro()
{
QString packagePath =
@@ -253,113 +89,3 @@ void AndroidDeployQtWidget::resetDefaultDevices()
AndroidConfigurations::clearDefaultDevices(m_step->project());
}
-void AndroidDeployQtWidget::signPackageCheckBoxToggled(bool checked)
-{
- m_ui->certificatesAliasComboBox->setEnabled(checked);
- m_step->setSignPackage(checked);
- updateSigningWarning();
- if (!checked)
- return;
- if (!m_step->keystorePath().isEmpty())
- setCertificates();
-}
-
-void AndroidDeployQtWidget::createKeyStore()
-{
- AndroidCreateKeystoreCertificate d;
- if (d.exec() != QDialog::Accepted)
- return;
- m_ui->KeystoreLocationPathChooser->setPath(d.keystoreFilePath().toUserOutput());
- m_step->setKeystorePath(d.keystoreFilePath());
- m_step->setKeystorePassword(d.keystorePassword());
- m_step->setCertificateAlias(d.certificateAlias());
- m_step->setCertificatePassword(d.certificatePassword());
- setCertificates();
-}
-
-void AndroidDeployQtWidget::setCertificates()
-{
- QAbstractItemModel *certificates = m_step->keystoreCertificates();
- m_ui->signPackageCheckBox->setChecked(certificates);
- m_ui->certificatesAliasComboBox->setModel(certificates);
-}
-
-void AndroidDeployQtWidget::updateKeyStorePath(const QString &path)
-{
- Utils::FileName file = Utils::FileName::fromString(path);
- m_step->setKeystorePath(file);
- m_ui->signPackageCheckBox->setChecked(!file.isEmpty());
- if (!file.isEmpty())
- setCertificates();
-}
-
-void AndroidDeployQtWidget::certificatesAliasComboBoxActivated(const QString &alias)
-{
- if (alias.length())
- m_step->setCertificateAlias(alias);
-}
-
-void AndroidDeployQtWidget::certificatesAliasComboBoxCurrentIndexChanged(const QString &alias)
-{
- if (alias.length())
- m_step->setCertificateAlias(alias);
-}
-
-void AndroidDeployQtWidget::openPackageLocationCheckBoxToggled(bool checked)
-{
- m_step->setOpenPackageLocation(checked);
-}
-
-void AndroidDeployQtWidget::verboseOutputCheckBoxToggled(bool checked)
-{
- m_step->setVerboseOutput(checked);
-}
-
-void AndroidDeployQtWidget::activeBuildConfigurationChanged()
-{
- if (m_currentBuildConfiguration)
- disconnect(m_currentBuildConfiguration, SIGNAL(qmakeBuildConfigurationChanged()),
- this, SLOT(updateSigningWarning()));
- updateSigningWarning();
- QmakeProjectManager::QmakeBuildConfiguration *bc
- = qobject_cast<QmakeProjectManager::QmakeBuildConfiguration *>(m_step->target()->activeBuildConfiguration());
- m_currentBuildConfiguration = bc;
- if (bc)
- connect(bc, SIGNAL(qmakeBuildConfigurationChanged()), this, SLOT(updateSigningWarning()));
- m_currentBuildConfiguration = bc;
-}
-
-void AndroidDeployQtWidget::updateSigningWarning()
-{
- QmakeProjectManager::QmakeBuildConfiguration *bc = qobject_cast<QmakeProjectManager::QmakeBuildConfiguration *>(m_step->target()->activeBuildConfiguration());
- bool debug = bc && (bc->qmakeBuildConfiguration() & QtSupport::BaseQtVersion::DebugBuild);
- if (m_step->signPackage() && debug) {
- m_ui->signingDebugWarningIcon->setVisible(true);
- m_ui->signingDebugWarningLabel->setVisible(true);
- } else {
- m_ui->signingDebugWarningIcon->setVisible(false);
- m_ui->signingDebugWarningLabel->setVisible(false);
- }
-}
-
-void AndroidDeployQtWidget::addAndroidExtraLib()
-{
- QStringList fileNames = QFileDialog::getOpenFileNames(this,
- tr("Select additional libraries"),
- m_currentBuildConfiguration->target()->project()->projectDirectory().toString(),
- tr("Libraries (*.so)"));
-
- if (!fileNames.isEmpty())
- m_extraLibraryListModel->addEntries(fileNames);
-}
-
-void AndroidDeployQtWidget::removeAndroidExtraLib()
-{
- QModelIndexList removeList = m_ui->androidExtraLibsListView->selectionModel()->selectedIndexes();
- m_extraLibraryListModel->removeEntries(removeList);
-}
-
-void AndroidDeployQtWidget::checkEnableRemoveButton()
-{
- m_ui->removeAndroidExtraLibButton->setEnabled(m_ui->androidExtraLibsListView->selectionModel()->hasSelection());
-}
diff --git a/src/plugins/android/androiddeployqtwidget.h b/src/plugins/android/androiddeployqtwidget.h
index d44a79186a..158b530593 100644
--- a/src/plugins/android/androiddeployqtwidget.h
+++ b/src/plugins/android/androiddeployqtwidget.h
@@ -38,12 +38,10 @@ QT_BEGIN_NAMESPACE
namespace Ui { class AndroidDeployQtWidget; }
QT_END_NAMESPACE
-namespace QmakeProjectManager { class QmakeBuildConfiguration; }
-
namespace Android {
namespace Internal {
class AndroidDeployQtStep;
-class AndroidExtraLibraryListModel;
+
class AndroidDeployQtWidget : public ProjectExplorer::BuildStepConfigWidget
{
Q_OBJECT
@@ -53,39 +51,16 @@ public:
~AndroidDeployQtWidget();
private slots:
- void setTargetSdk(const QString &sdk);
- void setMinistro();
- void setDeployLocalQtLibs();
- void setBundleQtLibs();
void installMinistro();
void cleanLibsOnDevice();
void resetDefaultDevices();
- void createKeyStore();
- void certificatesAliasComboBoxCurrentIndexChanged(const QString &alias);
- void certificatesAliasComboBoxActivated(const QString &alias);
- void activeBuildConfigurationChanged();
- void updateSigningWarning();
- void openPackageLocationCheckBoxToggled(bool checked);
- void verboseOutputCheckBoxToggled(bool checked);
- void updateKeyStorePath(const QString &path);
- void signPackageCheckBoxToggled(bool checked);
- void updateInputFileUi();
- void inputFileComboBoxIndexChanged();
- void createManifestButton();
- void addAndroidExtraLib();
- void removeAndroidExtraLib();
- void checkEnableRemoveButton();
private:
virtual QString summaryText() const;
virtual QString displayName() const;
- void setCertificates();
Ui::AndroidDeployQtWidget *m_ui;
AndroidDeployQtStep *m_step;
- AndroidExtraLibraryListModel *m_extraLibraryListModel;
- QmakeProjectManager::QmakeBuildConfiguration *m_currentBuildConfiguration;
- bool m_ignoreChange;
};
}
diff --git a/src/plugins/android/androiddeployqtwidget.ui b/src/plugins/android/androiddeployqtwidget.ui
index fc744a6955..204d1d886f 100644
--- a/src/plugins/android/androiddeployqtwidget.ui
+++ b/src/plugins/android/androiddeployqtwidget.ui
@@ -6,376 +6,53 @@
<rect>
<x>0</x>
<y>0</y>
- <width>682</width>
- <height>615</height>
+ <width>403</width>
+ <height>178</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="2" column="0" colspan="2">
- <widget class="QGroupBox" name="signPackage">
- <property name="title">
- <string>Sign package</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <widget class="QLabel" name="KeystoreLocationLabel">
- <property name="text">
- <string>Keystore:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="Utils::PathChooser" name="KeystoreLocationPathChooser" native="true"/>
- </item>
- <item>
- <widget class="QPushButton" name="KeystoreCreatePushButton">
- <property name="text">
- <string>Create...</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_4">
- <item>
- <widget class="QCheckBox" name="signPackageCheckBox">
- <property name="text">
- <string>Sign package</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <item>
- <widget class="QLabel" name="signingDebugWarningIcon">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="pixmap">
- <pixmap resource="../coreplugin/core.qrc">:/core/images/warning.png</pixmap>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="signingDebugWarningLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Signing a debug package</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="KeystoreLocationLabel_2">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Certificate alias:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="certificatesAliasComboBox">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>300</width>
- <height>0</height>
- </size>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item row="3" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
<widget class="QGroupBox" name="advancedActions">
<property name="title">
- <string>Advanced Actions</string>
+ <string>Deploy options</string>
</property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="4" column="0">
- <widget class="QPushButton" name="cleanLibsPushButton">
- <property name="text">
- <string>Clean Temporary Libraries Directory on Device</string>
- </property>
- </widget>
- </item>
- <item row="5" column="0">
- <widget class="QPushButton" name="installMinistroButton">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QCheckBox" name="uninstallPreviousPackage">
<property name="text">
- <string>Install Ministro from APK</string>
+ <string>Uninstall previous package</string>
</property>
</widget>
</item>
- <item row="3" column="0">
+ <item>
<widget class="QPushButton" name="resetDefaultDevices">
<property name="text">
<string>Reset Default Devices</string>
</property>
</widget>
</item>
- <item row="0" column="0">
- <widget class="QCheckBox" name="openPackageLocationCheckBox">
- <property name="text">
- <string>Open package location after build</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QCheckBox" name="verboseOutputCheckBox">
- <property name="text">
- <string>Verbose output</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QPushButton" name="createAndroidManifestButton">
- <property name="text">
- <string>Create AndroidManifest.xml</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="1" column="0" colspan="2">
- <widget class="QGroupBox" name="application">
- <property name="title">
- <string>Application</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="1" column="1">
- <widget class="QComboBox" name="targetSDKComboBox"/>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="targetSDKLabel">
- <property name="text">
- <string>Android build SDK:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="inputFileComboBox"/>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="inputFileLabel">
- <property name="text">
- <string>Input file for androiddeployqt:</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="0" column="0" colspan="2">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QLabel" name="oldFilesWarningIcon">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="pixmap">
- <pixmap resource="../coreplugin/core.qrc">:/core/images/warning.png</pixmap>
- </property>
- <property name="alignment">
- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="oldFilesWarningLabel">
- <property name="text">
- <string>Qt no longer uses the folder &quot;android&quot; in the project's source directory.</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="3" column="0">
- <widget class="QGroupBox" name="qtDeployment">
- <property name="title">
- <string>Qt Deployment</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QRadioButton" name="ministroOption">
- <property name="toolTip">
- <string>Uses the external Ministro application to download and maintain Qt libraries.&lt;br/&gt;&lt;br/&gt;Ministro is a third-party tool which provides the open source Qt libraries on demand. These libraries are compatible with the default open source binary package and will not always be up-to-date.</string>
- </property>
- <property name="text">
- <string>Use Ministro service to install Qt</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
<item>
- <widget class="QRadioButton" name="temporaryQtOption">
- <property name="toolTip">
- <string>Pushes local Qt libraries to device. You must have Qt libraries compiled for that platform.
-The APK will not be usable on any other device.</string>
- </property>
+ <widget class="QPushButton" name="cleanLibsPushButton">
<property name="text">
- <string>Deploy local Qt libraries to temporary directory</string>
+ <string>Clean Temporary Libraries Directory on Device</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="bundleQtOption">
- <property name="toolTip">
- <string>Creates a standalone APK.</string>
- </property>
+ <widget class="QPushButton" name="installMinistroButton">
<property name="text">
- <string>Bundle Qt libraries in APK</string>
+ <string>Install Ministro from APK</string>
</property>
</widget>
</item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- <item row="4" column="0" colspan="2">
- <widget class="QGroupBox" name="additionalLibrariesGroupBox">
- <property name="title">
- <string>Additional Libraries</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <item>
- <layout class="QHBoxLayout" name="androidExtraLibsLayout">
- <item>
- <widget class="QListView" name="androidExtraLibsListView">
- <property name="toolTip">
- <string>List of extra libraries to include in Android package and load on startup.</string>
- </property>
- <property name="selectionMode">
- <enum>QAbstractItemView::ExtendedSelection</enum>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QVBoxLayout" name="androidExtraLibsButtonLayout">
- <item>
- <widget class="QToolButton" name="addAndroidExtraLibButton">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Select library to include in package.</string>
- </property>
- <property name="text">
- <string>Add...</string>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextOnly</enum>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="removeAndroidExtraLibButton">
- <property name="toolTip">
- <string>Remove currently selected library from list.</string>
- </property>
- <property name="text">
- <string>Remove</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </item>
</layout>
</widget>
</item>
</layout>
</widget>
- <customwidgets>
- <customwidget>
- <class>Utils::PathChooser</class>
- <extends>QWidget</extends>
- <header location="global">utils/pathchooser.h</header>
- <container>1</container>
- </customwidget>
- </customwidgets>
- <resources>
- <include location="../projectexplorer/projectexplorer.qrc"/>
- </resources>
+ <resources/>
<connections/>
</ui>
diff --git a/src/plugins/android/androiddevice.h b/src/plugins/android/androiddevice.h
index ae119a96c3..3456bc0b90 100644
--- a/src/plugins/android/androiddevice.h
+++ b/src/plugins/android/androiddevice.h
@@ -33,9 +33,10 @@
#include <projectexplorer/devicesupport/idevice.h>
namespace Android {
-namespace Internal {
class AndroidConfigurations; // needed for friend declaration
+namespace Internal {
+
class AndroidDevice : public ProjectExplorer::IDevice
{
public:
@@ -54,7 +55,7 @@ public:
protected:
friend class AndroidDeviceFactory;
- friend class AndroidConfigurations;
+ friend class Android::AndroidConfigurations;
AndroidDevice();
AndroidDevice(const AndroidDevice &other);
};
diff --git a/src/plugins/android/androidglobal.h b/src/plugins/android/androidglobal.h
index dc93a878b4..04acc7a527 100644
--- a/src/plugins/android/androidglobal.h
+++ b/src/plugins/android/androidglobal.h
@@ -32,7 +32,7 @@
#include <utils/environment.h>
-#include <projectexplorer/deployconfiguration.h>
+#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/buildsteplist.h>
#define ASSERT_STATE_GENERIC(State, expected, actual) \
@@ -45,15 +45,17 @@ class AndroidGlobal
{
public:
- template<class T> static T *buildStep(const ProjectExplorer::DeployConfiguration *dc)
+ template<class T> static T *buildStep(const ProjectExplorer::BuildConfiguration *dc)
{
- ProjectExplorer::BuildStepList *bsl = dc->stepList();
- if (!bsl)
- return 0;
- const QList<ProjectExplorer::BuildStep *> &buildSteps = bsl->steps();
- for (int i = buildSteps.count() - 1; i >= 0; --i) {
- if (T * const step = qobject_cast<T *>(buildSteps.at(i)))
- return step;
+ for (const Core::Id &id : dc->knownStepLists()) {
+ ProjectExplorer::BuildStepList *bsl = dc->stepList(id);
+ if (!bsl)
+ return 0;
+ const QList<ProjectExplorer::BuildStep *> &buildSteps = bsl->steps();
+ for (int i = buildSteps.count() - 1; i >= 0; --i) {
+ if (T * const step = qobject_cast<T *>(buildSteps.at(i)))
+ return step;
+ }
}
return 0;
}
diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp
index cd22d4443c..922007e8e5 100644
--- a/src/plugins/android/androidmanager.cpp
+++ b/src/plugins/android/androidmanager.cpp
@@ -35,6 +35,8 @@
#include "androidtoolchain.h"
#include "androiddeployqtstep.h"
#include "androidqtsupport.h"
+#include "androidqtversion.h"
+#include "androidbuildapkstep.h"
#include <coreplugin/documentmanager.h>
#include <coreplugin/messagemanager.h>
@@ -42,13 +44,12 @@
#include <extensionsystem/pluginmanager.h>
+#include <projectexplorer/buildconfiguration.h>
+#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/session.h>
#include <projectexplorer/target.h>
-#include <qmakeprojectmanager/qmakenodes.h>
-#include <qmakeprojectmanager/qmakeproject.h>
-#include <qmakeprojectmanager/qmakeprojectmanagerconstants.h>
-#include <qmakeprojectmanager/qmakebuildconfiguration.h>
+
#include <qtsupport/customexecutablerunconfiguration.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtsupportconstants.h>
@@ -66,21 +67,26 @@ namespace {
const QLatin1String AndroidDirName("android");
const QLatin1String AndroidManifestName("AndroidManifest.xml");
const QLatin1String AndroidLibsFileName("/res/values/libs.xml");
- const QLatin1String AndroidStringsFileName("/res/values/strings.xml");
const QLatin1String AndroidDefaultPropertiesName("project.properties");
+ const QLatin1String AndroidDeviceSn("AndroidDeviceSerialNumber");
+
} // anonymous namespace
namespace Android {
-namespace Internal {
-bool AndroidManager::supportsAndroid(ProjectExplorer::Target *target)
+using namespace Internal;
+
+bool AndroidManager::supportsAndroid(const ProjectExplorer::Kit *kit)
{
- if (!qobject_cast<QmakeProjectManager::QmakeProject *>(target->project()))
- return false;
- QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target->kit());
+ QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(kit);
return version && version->platformName() == QLatin1String(QtSupport::Constants::ANDROID_PLATFORM);
}
+bool AndroidManager::supportsAndroid(const ProjectExplorer::Target *target)
+{
+ return supportsAndroid(target->kit());
+}
+
QString AndroidManager::packageName(ProjectExplorer::Target *target)
{
QDomDocument doc;
@@ -124,23 +130,28 @@ int AndroidManager::minimumSDK(ProjectExplorer::Target *target)
QString AndroidManager::buildTargetSDK(ProjectExplorer::Target *target)
{
- if (!target->activeDeployConfiguration())
- return QLatin1String("android-9");
- AndroidDeployQtStep *step = AndroidGlobal::buildStep<AndroidDeployQtStep>(target->activeDeployConfiguration());
- if (step)
- return step->buildTargetSdk();
- return QLatin1String("android-9");
+ AndroidBuildApkStep *androidBuildApkStep
+ = AndroidGlobal::buildStep<AndroidBuildApkStep>(target->activeBuildConfiguration());
+ if (androidBuildApkStep)
+ return androidBuildApkStep->buildTargetSdk();
+
+ QString fallback = AndroidConfig::apiLevelNameFor(AndroidConfigurations::currentConfig().highestAndroidSdk());
+ return fallback;
+}
+
+bool AndroidManager::signPackage(ProjectExplorer::Target *target)
+{
+ AndroidBuildApkStep *androidBuildApkStep
+ = AndroidGlobal::buildStep<AndroidBuildApkStep>(target->activeBuildConfiguration());
+ if (androidBuildApkStep)
+ return androidBuildApkStep->signPackage();
+ return false;
}
QString AndroidManager::targetArch(ProjectExplorer::Target *target)
{
- QmakeProjectManager::QmakeProject *pro = qobject_cast<QmakeProjectManager::QmakeProject *>(target->project());
- if (!pro)
- return QString();
- QmakeProjectManager::QmakeProFileNode *node = pro->rootQmakeProjectNode();
- if (!node)
- return QString();
- return node->singleVariableValue(QmakeProjectManager::AndroidArchVar);
+ AndroidQtVersion *qt = static_cast<AndroidQtVersion *>(QtSupport::QtKitInformation::qtVersion(target->kit()));
+ return qt->targetArch();
}
Utils::FileName AndroidManager::dirPath(ProjectExplorer::Target *target)
@@ -163,60 +174,23 @@ Utils::FileName AndroidManager::defaultPropertiesPath(ProjectExplorer::Target *t
return dirPath(target).appendPath(AndroidDefaultPropertiesName);
}
-Utils::FileName AndroidManager::apkPath(ProjectExplorer::Target *target, BuildType buildType)
-{
- QString packageName = QLatin1String("QtApp");
- QString buildTypeName;
- if (buildType == DebugBuild)
- buildTypeName = QLatin1String("debug");
- else if (buildType == ReleaseBuildUnsigned)
- buildTypeName =QLatin1String("release-unsigned");
- else
- buildTypeName = QLatin1String("release");
-
- return dirPath(target)
- .appendPath(QLatin1String("bin"))
- .appendPath(QString::fromLatin1("%1-%2.apk")
- .arg(packageName)
- .arg(buildTypeName));
-}
-
-QStringList AndroidManager::availableTargetApplications(ProjectExplorer::Target *target)
-{
- QStringList apps;
- QmakeProjectManager::QmakeProject *qmakeProject = qobject_cast<QmakeProjectManager::QmakeProject *>(target->project());
- if (!qmakeProject)
- return apps;
- foreach (QmakeProjectManager::QmakeProFileNode *proFile, qmakeProject->applicationProFiles()) {
- if (proFile->projectType() == QmakeProjectManager::ApplicationTemplate) {
- if (proFile->targetInformation().target.startsWith(QLatin1String("lib"))
- && proFile->targetInformation().target.endsWith(QLatin1String(".so")))
- apps << proFile->targetInformation().target.mid(3, proFile->targetInformation().target.lastIndexOf(QLatin1Char('.')) - 3);
- else
- apps << proFile->targetInformation().target;
- }
- }
- apps.sort();
- return apps;
-}
-
bool AndroidManager::bundleQt(ProjectExplorer::Target *target)
{
- AndroidDeployQtStep *androidDeployQtStep
- = AndroidGlobal::buildStep<AndroidDeployQtStep>(target->activeDeployConfiguration());
- if (androidDeployQtStep)
- return androidDeployQtStep->deployAction() == AndroidDeployQtStep::BundleLibrariesDeployment;
+ AndroidBuildApkStep *androidBuildApkStep
+ = AndroidGlobal::buildStep<AndroidBuildApkStep>(target->activeBuildConfiguration());
+ if (androidBuildApkStep)
+ return androidBuildApkStep->deployAction() == AndroidBuildApkStep::BundleLibrariesDeployment;
return false;
}
bool AndroidManager::useLocalLibs(ProjectExplorer::Target *target)
{
- AndroidDeployQtStep *androidDeployQtStep
- = AndroidGlobal::buildStep<AndroidDeployQtStep>(target->activeDeployConfiguration());
- if (androidDeployQtStep) {
- return androidDeployQtStep->deployAction() == AndroidDeployQtStep::DebugDeployment
- || androidDeployQtStep->deployAction() == AndroidDeployQtStep::BundleLibrariesDeployment;
+ AndroidBuildApkStep *androidBuildApkStep
+ = AndroidGlobal::buildStep<AndroidBuildApkStep>(target->activeBuildConfiguration());
+ if (androidBuildApkStep) {
+ return androidBuildApkStep->deployAction() == AndroidBuildApkStep::DebugDeployment
+ || androidBuildApkStep->deployAction() == AndroidBuildApkStep::BundleLibrariesDeployment;
}
return false;
@@ -224,11 +198,12 @@ bool AndroidManager::useLocalLibs(ProjectExplorer::Target *target)
QString AndroidManager::deviceSerialNumber(ProjectExplorer::Target *target)
{
- AndroidDeployQtStep *androidDeployQtStep
- = AndroidGlobal::buildStep<AndroidDeployQtStep>(target->activeDeployConfiguration());
- if (androidDeployQtStep)
- return androidDeployQtStep->deviceSerialNumber();
- return QString();
+ return target->namedSettings(AndroidDeviceSn).toString();
+}
+
+void AndroidManager::setDeviceSerialNumber(ProjectExplorer::Target *target, const QString &deviceSerialNumber)
+{
+ target->setNamedSettings(AndroidDeviceSn, deviceSerialNumber);
}
Utils::FileName AndroidManager::localLibsRulesFilePath(ProjectExplorer::Target *target)
@@ -688,5 +663,4 @@ AndroidQtSupport *AndroidManager::androidQtSupport(ProjectExplorer::Target *targ
return 0;
}
-} // namespace Internal
} // namespace Android
diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h
index 44eb9b57ab..04345ba659 100644
--- a/src/plugins/android/androidmanager.h
+++ b/src/plugins/android/androidmanager.h
@@ -30,45 +30,47 @@
#ifndef ANDROIDMANAGER_H
#define ANDROIDMANAGER_H
+#include "android_global.h"
#include <utils/fileutils.h>
-#include <QDomDocument>
#include <QPair>
#include <QObject>
#include <QStringList>
-namespace ProjectExplorer { class Target; }
+class QDomDocument;
+
+namespace ProjectExplorer {
+class Kit;
+class Target;
+}
namespace Android {
+
class AndroidQtSupport;
-namespace Internal {
-class AndroidManager : public QObject
+class ANDROID_EXPORT AndroidManager : public QObject
{
Q_OBJECT
public:
- enum BuildType
- {
- DebugBuild,
- ReleaseBuildUnsigned,
- ReleaseBuildSigned
- };
- static bool supportsAndroid(ProjectExplorer::Target *target);
+ static bool supportsAndroid(const ProjectExplorer::Kit *kit);
+ static bool supportsAndroid(const ProjectExplorer::Target *target);
static QString packageName(ProjectExplorer::Target *target);
static QString intentName(ProjectExplorer::Target *target);
static QString activityName(ProjectExplorer::Target *target);
- static QStringList availableTargetApplications(ProjectExplorer::Target *target);
-
static bool bundleQt(ProjectExplorer::Target *target);
static bool useLocalLibs(ProjectExplorer::Target *target);
static QString deviceSerialNumber(ProjectExplorer::Target *target);
+ static void setDeviceSerialNumber(ProjectExplorer::Target *target, const QString &deviceSerialNumber);
static QString buildTargetSDK(ProjectExplorer::Target *target);
+
+ static bool signPackage(ProjectExplorer::Target *target);
+
static int minimumSDK(ProjectExplorer::Target *target);
static QString targetArch(ProjectExplorer::Target *target);
@@ -77,7 +79,6 @@ public:
static Utils::FileName manifestPath(ProjectExplorer::Target *target);
static Utils::FileName libsPath(ProjectExplorer::Target *target);
static Utils::FileName defaultPropertiesPath(ProjectExplorer::Target *target);
- static Utils::FileName apkPath(ProjectExplorer::Target *target, BuildType buildType);
static Utils::FileName localLibsRulesFilePath(ProjectExplorer::Target *target);
static QString loadLocalLibs(ProjectExplorer::Target *target, int apiLevel = -1);
@@ -134,7 +135,6 @@ private:
};
-} // namespace Internal
} // namespace Android
#endif // ANDROIDMANAGER_H
diff --git a/src/plugins/android/androidmanifesteditorwidget.cpp b/src/plugins/android/androidmanifesteditorwidget.cpp
index f0f6e7af33..bc94f74c9e 100644
--- a/src/plugins/android/androidmanifesteditorwidget.cpp
+++ b/src/plugins/android/androidmanifesteditorwidget.cpp
@@ -32,12 +32,13 @@
#include "androidconstants.h"
#include "androidmanifestdocument.h"
#include "androidmanager.h"
+#include "androidqtsupport.h"
#include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h>
#include <coreplugin/infobar.h>
#include <coreplugin/editormanager/ieditor.h>
-#include <texteditor/plaintexteditor.h>
+
#include <projectexplorer/project.h>
#include <projectexplorer/projectwindow.h>
#include <projectexplorer/iprojectproperties.h>
@@ -45,9 +46,10 @@
#include <projectexplorer/target.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/kitinformation.h>
+
#include <texteditor/texteditoractionhandler.h>
#include <texteditor/texteditorsettings.h>
-#include <qmakeprojectmanager/qmakeproject.h>
+#include <texteditor/plaintexteditor.h>
#include <utils/algorithm.h>
#include <QLineEdit>
@@ -476,7 +478,7 @@ void AndroidManifestEditorWidget::updateTargetComboBox()
if (project) {
ProjectExplorer::Kit *kit = project->activeTarget()->kit();
if (ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(kit) == Constants::ANDROID_DEVICE_TYPE)
- items = AndroidManager::availableTargetApplications(project->activeTarget());
+ items = AndroidManager::androidQtSupport(project->activeTarget())->projectTargetApplications(project->activeTarget());
}
// QComboBox randomly resets what the user has entered
diff --git a/src/plugins/android/androidplugin.cpp b/src/plugins/android/androidplugin.cpp
index cf90b06134..ff0592fd31 100644
--- a/src/plugins/android/androidplugin.cpp
+++ b/src/plugins/android/androidplugin.cpp
@@ -35,7 +35,6 @@
#include "androiddevice.h"
#include "androiddevicefactory.h"
#include "androidmanager.h"
-#include "androidpackageinstallationfactory.h"
#include "androidrunfactories.h"
#include "androidsettingspage.h"
#include "androidtoolchain.h"
@@ -47,8 +46,6 @@
#include "javaeditorfactory.h"
#include "javacompletionassistprovider.h"
#include "javafilewizard.h"
-#include "qmakeandroidsupport.h"
-#include "qmakeandroidrunfactories.h"
#ifdef HAVE_QBS
# include "androidqbspropertyprovider.h"
#endif
@@ -72,11 +69,9 @@ bool AndroidPlugin::initialize(const QStringList &arguments, QString *errorMessa
Q_UNUSED(arguments);
Q_UNUSED(errorMessage);
- new Internal::AndroidConfigurations(this);
+ new AndroidConfigurations(this);
addAutoReleasedObject(new Internal::AndroidRunControlFactory);
- addAutoReleasedObject(new Internal::QmakeAndroidRunConfigurationFactory);
- addAutoReleasedObject(new Internal::AndroidPackageInstallationFactory);
addAutoReleasedObject(new Internal::AndroidDeployQtStepFactory);
addAutoReleasedObject(new Internal::AndroidSettingsPage);
addAutoReleasedObject(new Internal::AndroidQtVersionFactory);
@@ -87,7 +82,6 @@ bool AndroidPlugin::initialize(const QStringList &arguments, QString *errorMessa
addAutoReleasedObject(new Internal::JavaEditorFactory);
addAutoReleasedObject(new Internal::JavaCompletionAssistProvider);
addAutoReleasedObject(new Internal::JavaFileWizard);
- addAutoReleasedObject(new Internal::QmakeAndroidSupport);
ProjectExplorer::KitManager::registerKitInformation(new Internal::AndroidGdbServerKitInformation);
// AndroidManifest.xml editor
@@ -117,16 +111,16 @@ bool AndroidPlugin::initialize(const QStringList &arguments, QString *errorMessa
void AndroidPlugin::kitsRestored()
{
- Internal::AndroidConfigurations::updateAutomaticKitList();
+ AndroidConfigurations::updateAutomaticKitList();
connect(QtSupport::QtVersionManager::instance(), SIGNAL(qtVersionsChanged(QList<int>,QList<int>,QList<int>)),
- Internal::AndroidConfigurations::instance(), SLOT(updateAutomaticKitList()));
+ AndroidConfigurations::instance(), SLOT(updateAutomaticKitList()));
disconnect(ProjectExplorer::KitManager::instance(), SIGNAL(kitsChanged()),
this, SLOT(kitsRestored()));
}
void AndroidPlugin::updateDevice()
{
- Internal::AndroidConfigurations::updateAndroidDevice();
+ AndroidConfigurations::updateAndroidDevice();
}
} // namespace Android
diff --git a/src/plugins/android/androidqtsupport.h b/src/plugins/android/androidqtsupport.h
index 8e60612151..96cbf342f8 100644
--- a/src/plugins/android/androidqtsupport.h
+++ b/src/plugins/android/androidqtsupport.h
@@ -58,10 +58,13 @@ public:
ReleaseBuildSigned
};
-
public:
virtual bool canHandle(const ProjectExplorer::Target *target) const = 0;
virtual QStringList soLibSearchPath(const ProjectExplorer::Target *target) const = 0;
+ virtual QStringList projectTargetApplications(const ProjectExplorer::Target *target) const = 0;
+ virtual Utils::FileName apkPath(ProjectExplorer::Target *target, BuildType buildType) const = 0;
+
+ virtual void resetBuild(const ProjectExplorer::Target *target) = 0;
};
} // namespace QtSupport
diff --git a/src/plugins/android/androidqtversion.cpp b/src/plugins/android/androidqtversion.cpp
index 559dd28f13..c808ecfb29 100644
--- a/src/plugins/android/androidqtversion.cpp
+++ b/src/plugins/android/androidqtversion.cpp
@@ -35,22 +35,19 @@
#include <utils/environment.h>
#include <utils/hostosinfo.h>
-#include <qmakeprojectmanager/qmakeproject.h>
-#include <qmakeprojectmanager/qmakeprojectmanagerconstants.h>
-
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtsupportconstants.h>
#include <qtsupport/qtversionmanager.h>
#include <projectexplorer/target.h>
#include <projectexplorer/kit.h>
+#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorer.h>
#include <proparser/profileevaluator.h>
using namespace Android::Internal;
using namespace ProjectExplorer;
-using namespace QmakeProjectManager;
AndroidQtVersion::AndroidQtVersion()
: QtSupport::BaseQtVersion()
@@ -109,12 +106,12 @@ void AndroidQtVersion::addToEnvironment(const ProjectExplorer::Kit *k, Utils::En
env.set(QLatin1String("ANDROID_NDK_HOST"), AndroidConfigurations::currentConfig().toolchainHost());
env.set(QLatin1String("ANDROID_NDK_ROOT"), AndroidConfigurations::currentConfig().ndkLocation().toUserOutput());
- QmakeProject *qmakeProject = qobject_cast<QmakeProjectManager::QmakeProject *>(ProjectExplorerPlugin::instance()->currentProject());
- if (!qmakeProject || !qmakeProject->activeTarget()
+ Project *project = ProjectExplorerPlugin::instance()->currentProject();
+ if (!project || !project->activeTarget()
|| QtSupport::QtKitInformation::qtVersion(k)->type() != QLatin1String(Constants::ANDROIDQT))
return;
- Target *target = qmakeProject->activeTarget();
+ Target *target = project->activeTarget();
if (DeviceTypeKitInformation::deviceTypeId(target->kit()) != Constants::ANDROID_DEVICE_TYPE)
return;
if (AndroidConfigurations::currentConfig().ndkLocation().isEmpty()
diff --git a/src/plugins/android/androidruncontrol.h b/src/plugins/android/androidruncontrol.h
index 2f6d87acdc..ab624b507d 100644
--- a/src/plugins/android/androidruncontrol.h
+++ b/src/plugins/android/androidruncontrol.h
@@ -36,7 +36,6 @@ namespace Android {
class AndroidRunConfiguration;
namespace Internal {
-
class AndroidRunner;
class AndroidRunControl : public ProjectExplorer::RunControl
diff --git a/src/plugins/android/androidrunner.h b/src/plugins/android/androidrunner.h
index be0c48216a..9e9fee4b52 100644
--- a/src/plugins/android/androidrunner.h
+++ b/src/plugins/android/androidrunner.h
@@ -45,7 +45,6 @@ class AndroidRunConfiguration;
namespace Internal {
-
class AndroidRunner : public QThread
{
Q_OBJECT
diff --git a/src/plugins/android/avddialog.h b/src/plugins/android/avddialog.h
index d0aefc2221..706da287a9 100644
--- a/src/plugins/android/avddialog.h
+++ b/src/plugins/android/avddialog.h
@@ -34,9 +34,10 @@
#include <QDialog>
namespace Android {
-namespace Internal {
class AndroidConfig;
+namespace Internal {
+
class AvdDialog : public QDialog
{
Q_OBJECT
diff --git a/src/plugins/projectexplorer/settingsaccessor.cpp b/src/plugins/projectexplorer/settingsaccessor.cpp
index 101d77546b..42ae2a179e 100644
--- a/src/plugins/projectexplorer/settingsaccessor.cpp
+++ b/src/plugins/projectexplorer/settingsaccessor.cpp
@@ -321,6 +321,37 @@ public:
QString backupExtension() const { return QLatin1String("3.2-pre1"); }
QVariantMap upgrade(const QVariantMap &map);
};
+
+// Version 16 Changed android deployment
+class UserFileVersion16Upgrader : public VersionUpgrader
+{
+public:
+ int version() const { return 16; }
+ QString backupExtension() const { return QLatin1String("3.3-pre1"); }
+ QVariantMap upgrade(const QVariantMap &data);
+private:
+ class OldStepMaps
+ {
+ public:
+ QString defaultDisplayName;
+ QString displayName;
+ QVariantMap androidPackageInstall;
+ QVariantMap androidDeployQt;
+ bool isEmpty()
+ {
+ return androidPackageInstall.isEmpty() || androidDeployQt.isEmpty();
+ }
+ };
+
+
+ QVariantMap removeAndroidPackageStep(QVariantMap deployMap);
+ OldStepMaps extractStepMaps(const QVariantMap &deployMap);
+ enum NamePolicy { KeepName, RenameBuildConfiguration };
+ QVariantMap insertSteps(QVariantMap buildConfigurationMap,
+ const OldStepMaps &oldStepMap,
+ NamePolicy policy);
+};
+
} // namespace
//
@@ -403,6 +434,7 @@ UserFileAccessor::UserFileAccessor(Project *project)
addVersionUpgrader(new UserFileVersion13Upgrader);
addVersionUpgrader(new UserFileVersion14Upgrader);
addVersionUpgrader(new UserFileVersion15Upgrader);
+ addVersionUpgrader(new UserFileVersion16Upgrader);
}
QVariantMap UserFileAccessor::prepareSettings(const QVariantMap &data) const
@@ -2401,3 +2433,221 @@ QVariantMap UserFileVersion15Upgrader::upgrade(const QVariantMap &map)
return renameKeys(changes, QVariantMap(map));
}
+
+// --------------------------------------------------------------------
+// UserFileVersion16Upgrader:
+// --------------------------------------------------------------------
+
+UserFileVersion16Upgrader::OldStepMaps UserFileVersion16Upgrader::extractStepMaps(const QVariantMap &deployMap)
+{
+ OldStepMaps result;
+ result.defaultDisplayName = deployMap.value(QLatin1String("ProjectExplorer.ProjectConfiguration.DefaultDisplayName")).toString();
+ result.displayName = deployMap.value(QLatin1String("ProjectExplorer.ProjectConfiguration.DisplayName")).toString();
+ const QString stepListKey = QLatin1String("ProjectExplorer.BuildConfiguration.BuildStepList.0");
+ QVariantMap stepListMap = deployMap.value(stepListKey).toMap();
+ int stepCount = stepListMap.value(QLatin1String("ProjectExplorer.BuildStepList.StepsCount"), 0).toInt();
+ QString stepKey = QLatin1String("ProjectExplorer.BuildStepList.Step.");
+ for (int i = 0; i < stepCount; ++i) {
+ QVariantMap stepMap = stepListMap.value(stepKey + QString::number(i)).toMap();
+ const QString id = stepMap.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id")).toString();
+ if (id == QLatin1String("Qt4ProjectManager.AndroidDeployQtStep"))
+ result.androidDeployQt = stepMap;
+ else if (id == QLatin1String("Qt4ProjectManager.AndroidPackageInstallationStep"))
+ result.androidPackageInstall = stepMap;
+ if (!result.isEmpty())
+ return result;
+
+ }
+ return result;
+}
+
+QVariantMap UserFileVersion16Upgrader::removeAndroidPackageStep(QVariantMap deployMap)
+{
+ const QString stepListKey = QLatin1String("ProjectExplorer.BuildConfiguration.BuildStepList.0");
+ QVariantMap stepListMap = deployMap.value(stepListKey).toMap();
+ const QString stepCountKey = QLatin1String("ProjectExplorer.BuildStepList.StepsCount");
+ int stepCount = stepListMap.value(stepCountKey, 0).toInt();
+ QString stepKey = QLatin1String("ProjectExplorer.BuildStepList.Step.");
+ int targetPosition = 0;
+ for (int sourcePosition = 0; sourcePosition < stepCount; ++sourcePosition) {
+ QVariantMap stepMap = stepListMap.value(stepKey + QString::number(sourcePosition)).toMap();
+ if (stepMap.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id")).toString()
+ != QLatin1String("Qt4ProjectManager.AndroidPackageInstallationStep")) {
+ stepListMap.insert(stepKey + QString::number(targetPosition), stepMap);
+ ++targetPosition;
+ }
+ }
+
+ stepListMap.insert(stepCountKey, targetPosition);
+
+ for (int i = targetPosition; i < stepCount; ++i)
+ stepListMap.remove(stepKey + QString::number(i));
+
+ deployMap.insert(stepListKey, stepListMap);
+ return deployMap;
+}
+
+QVariantMap UserFileVersion16Upgrader::insertSteps(QVariantMap buildConfigurationMap,
+ const OldStepMaps &oldStepMap,
+ NamePolicy policy)
+{
+ const QString bslCountKey = QLatin1String("ProjectExplorer.BuildConfiguration.BuildStepListCount");
+ int stepListCount = buildConfigurationMap.value(bslCountKey).toInt();
+
+ const QString bslKey = QLatin1String("ProjectExplorer.BuildConfiguration.BuildStepList.");
+ const QString bslTypeKey = QLatin1String("ProjectExplorer.ProjectConfiguration.Id");
+ for (int bslNumber = 0; bslNumber < stepListCount; ++bslNumber) {
+ QVariantMap buildStepListMap = buildConfigurationMap.value(bslKey + QString::number(bslNumber)).toMap();
+ if (buildStepListMap.value(bslTypeKey) != QLatin1String("ProjectExplorer.BuildSteps.Build"))
+ continue;
+
+ const QString bslStepCountKey = QLatin1String("ProjectExplorer.BuildStepList.StepsCount");
+
+ int stepCount = buildStepListMap.value(bslStepCountKey).toInt();
+ buildStepListMap.insert(bslStepCountKey, stepCount + 2);
+
+ QVariantMap androidPackageInstallStep;
+ QVariantMap androidBuildApkStep;
+
+ // common settings of all buildsteps
+ const QString enabledKey = QLatin1String("ProjectExplorer.BuildStep.Enabled");
+ const QString idKey = QLatin1String("ProjectExplorer.ProjectConfiguration.Id");
+ const QString displayNameKey = QLatin1String("ProjectExplorer.ProjectConfiguration.DisplayName");
+ const QString defaultDisplayNameKey = QLatin1String("ProjectExplorer.ProjectConfiguration.DefaultDisplayName");
+
+ QString displayName = oldStepMap.androidPackageInstall.value(displayNameKey).toString();
+ QString defaultDisplayName = oldStepMap.androidPackageInstall.value(defaultDisplayNameKey).toString();
+ bool enabled = oldStepMap.androidPackageInstall.value(enabledKey).toBool();
+
+ androidPackageInstallStep.insert(idKey, Core::Id("Qt4ProjectManager.AndroidPackageInstallationStep").toSetting());
+ androidPackageInstallStep.insert(displayNameKey, displayName);
+ androidPackageInstallStep.insert(defaultDisplayNameKey, defaultDisplayName);
+ androidPackageInstallStep.insert(enabledKey, enabled);
+
+ displayName = oldStepMap.androidDeployQt.value(displayName).toString();
+ defaultDisplayName = oldStepMap.androidDeployQt.value(defaultDisplayNameKey).toString();
+ enabled = oldStepMap.androidDeployQt.value(enabledKey).toBool();
+
+ androidBuildApkStep.insert(idKey, Core::Id("QmakeProjectManager.AndroidBuildApkStep").toSetting());
+ androidBuildApkStep.insert(displayNameKey, displayName);
+ androidBuildApkStep.insert(defaultDisplayNameKey, defaultDisplayName);
+ androidBuildApkStep.insert(enabledKey, enabled);
+
+ // settings transferred from AndroidDeployQtStep to QmakeBuildApkStep
+ const QString ProFilePathForInputFile = QLatin1String("ProFilePathForInputFile");
+ const QString DeployActionKey = QLatin1String("Qt4ProjectManager.AndroidDeployQtStep.DeployQtAction");
+ const QString KeystoreLocationKey = QLatin1String("KeystoreLocation");
+ const QString BuildTargetSdkKey = QLatin1String("BuildTargetSdk");
+ const QString VerboseOutputKey = QLatin1String("VerboseOutput");
+
+ QString inputFile = oldStepMap.androidDeployQt.value(ProFilePathForInputFile).toString();
+ int oldDeployAction = oldStepMap.androidDeployQt.value(DeployActionKey).toInt();
+ QString keyStorePath = oldStepMap.androidDeployQt.value(KeystoreLocationKey).toString();
+ QString buildTargetSdk = oldStepMap.androidDeployQt.value(BuildTargetSdkKey).toString();
+ bool verbose = oldStepMap.androidDeployQt.value(VerboseOutputKey).toBool();
+ androidBuildApkStep.insert(ProFilePathForInputFile, inputFile);
+ androidBuildApkStep.insert(DeployActionKey, oldDeployAction);
+ androidBuildApkStep.insert(KeystoreLocationKey, keyStorePath);
+ androidBuildApkStep.insert(BuildTargetSdkKey, buildTargetSdk);
+ androidBuildApkStep.insert(VerboseOutputKey, verbose);
+
+ const QString buildStepKey = QLatin1String("ProjectExplorer.BuildStepList.Step.");
+ buildStepListMap.insert(buildStepKey + QString::number(stepCount), androidPackageInstallStep);
+ buildStepListMap.insert(buildStepKey + QString::number(stepCount + 1), androidBuildApkStep);
+
+ buildConfigurationMap.insert(bslKey + QString::number(bslNumber), buildStepListMap);
+ }
+
+ if (policy == RenameBuildConfiguration) {
+ const QString displayNameKey = QLatin1String("ProjectExplorer.ProjectConfiguration.DisplayName");
+ const QString defaultDisplayNameKey = QLatin1String("ProjectExplorer.ProjectConfiguration.DefaultDisplayName");
+
+ QString defaultDisplayName = buildConfigurationMap.value(defaultDisplayNameKey).toString();
+ QString displayName = buildConfigurationMap.value(displayNameKey).toString();
+ if (displayName.isEmpty())
+ displayName = defaultDisplayName;
+ QString oldDisplayname = oldStepMap.displayName;
+ if (oldDisplayname.isEmpty())
+ oldDisplayname = oldStepMap.defaultDisplayName;
+
+ displayName.append(QLatin1String(" - "));
+ displayName.append(oldDisplayname);
+ buildConfigurationMap.insert(displayNameKey, displayName);
+
+ defaultDisplayName.append(QLatin1String(" - "));
+ defaultDisplayName.append(oldStepMap.defaultDisplayName);
+ buildConfigurationMap.insert(defaultDisplayNameKey, defaultDisplayName);
+ }
+
+ return buildConfigurationMap;
+}
+
+QVariantMap UserFileVersion16Upgrader::upgrade(const QVariantMap &data)
+{
+ int targetCount = data.value(QLatin1String("ProjectExplorer.Project.TargetCount"), 0).toInt();
+ if (!targetCount)
+ return data;
+
+ QVariantMap result = data;
+
+ for (int i = 0; i < targetCount; ++i) {
+ QString targetKey = QLatin1String("ProjectExplorer.Project.Target.") + QString::number(i);
+ QVariantMap targetMap = data.value(targetKey).toMap();
+
+ const QString dcCountKey = QLatin1String("ProjectExplorer.Target.DeployConfigurationCount");
+ int deployconfigurationCount = targetMap.value(dcCountKey).toInt();
+ if (!deployconfigurationCount) // should never happen
+ continue;
+
+ QList<OldStepMaps> oldSteps;
+ QList<QVariantMap> oldBuildConfigurations;
+
+ QString deployKey = QLatin1String("ProjectExplorer.Target.DeployConfiguration.");
+ for (int j = 0; j < deployconfigurationCount; ++j) {
+ QVariantMap deployConfigurationMap
+ = targetMap.value(deployKey + QString::number(j)).toMap();
+ OldStepMaps oldStep = extractStepMaps(deployConfigurationMap);
+ if (!oldStep.isEmpty()) {
+ oldSteps.append(oldStep);
+ deployConfigurationMap = removeAndroidPackageStep(deployConfigurationMap);
+ targetMap.insert(deployKey + QString::number(j), deployConfigurationMap);
+ }
+ }
+
+ if (oldSteps.isEmpty()) // no android target?
+ continue;
+
+ const QString bcCountKey = QLatin1String("ProjectExplorer.Target.BuildConfigurationCount");
+ int buildConfigurationCount
+ = targetMap.value(bcCountKey).toInt();
+
+ if (!buildConfigurationCount) // should never happen
+ continue;
+
+ QString bcKey = QLatin1String("ProjectExplorer.Target.BuildConfiguration.");
+ for (int j = 0; j < buildConfigurationCount; ++j) {
+ QVariantMap oldBuildConfigurationMap = targetMap.value(bcKey + QString::number(j)).toMap();
+ oldBuildConfigurations.append(oldBuildConfigurationMap);
+ }
+
+ QList<QVariantMap> newBuildConfigurations;
+
+ NamePolicy policy = oldSteps.size() > 1 ? RenameBuildConfiguration : KeepName;
+
+ foreach (const QVariantMap &oldBuildConfiguration, oldBuildConfigurations) {
+ foreach (const OldStepMaps &oldStep, oldSteps) {
+ QVariantMap newBuildConfiguration = insertSteps(oldBuildConfiguration, oldStep, policy);
+ if (!newBuildConfiguration.isEmpty())
+ newBuildConfigurations.append(newBuildConfiguration);
+ }
+ }
+
+ targetMap.insert(bcCountKey, newBuildConfigurations.size());
+
+ for (int j = 0; j < newBuildConfigurations.size(); ++j)
+ targetMap.insert(bcKey + QString::number(j), newBuildConfigurations.at(j));
+ result.insert(targetKey, targetMap);
+ }
+
+ return result;
+}
diff --git a/src/plugins/android/androidextralibrarylistmodel.cpp b/src/plugins/qmakeprojectmanager/androidextralibrarylistmodel.cpp
index b2499bcc0b..fc509457cb 100644
--- a/src/plugins/android/androidextralibrarylistmodel.cpp
+++ b/src/plugins/qmakeprojectmanager/androidextralibrarylistmodel.cpp
@@ -33,7 +33,7 @@
#include <qmakeprojectmanager/qmakenodes.h>
#include <proparser/prowriter.h>
-using namespace Android;
+using namespace QmakeProjectManager;
using namespace Internal;
AndroidExtraLibraryListModel::AndroidExtraLibraryListModel(QmakeProjectManager::QmakeProject *project,
diff --git a/src/plugins/android/androidextralibrarylistmodel.h b/src/plugins/qmakeprojectmanager/androidextralibrarylistmodel.h
index 86e82672ea..acc7adea61 100644
--- a/src/plugins/android/androidextralibrarylistmodel.h
+++ b/src/plugins/qmakeprojectmanager/androidextralibrarylistmodel.h
@@ -37,9 +37,7 @@
namespace QmakeProjectManager {
class QmakeProject;
class QmakeProFileNode;
-}
-namespace Android {
namespace Internal {
class AndroidExtraLibraryListModel : public QAbstractItemModel
{
@@ -72,6 +70,6 @@ private:
};
} // namespace Internal
-} // namespace Android
+} // namespace QmakeProjectManager
#endif // ANDROIDEXTRALIBRARYLISTMODEL_H
diff --git a/src/plugins/android/androidpackageinstallationfactory.cpp b/src/plugins/qmakeprojectmanager/androidpackageinstallationfactory.cpp
index 791f9a7bea..a4ea9c378e 100644
--- a/src/plugins/android/androidpackageinstallationfactory.cpp
+++ b/src/plugins/qmakeprojectmanager/androidpackageinstallationfactory.cpp
@@ -28,19 +28,18 @@
****************************************************************************/
#include "androidpackageinstallationfactory.h"
-
#include "androidpackageinstallationstep.h"
-#include "androidmanager.h"
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/target.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtsupportconstants.h>
+#include <android/androidmanager.h>
using namespace ProjectExplorer;
-namespace Android {
+namespace QmakeProjectManager {
namespace Internal {
AndroidPackageInstallationFactory::AndroidPackageInstallationFactory(QObject *parent)
@@ -77,9 +76,9 @@ BuildStep *AndroidPackageInstallationFactory::create(BuildStepList *parent, Core
bool AndroidPackageInstallationFactory::canRestore(BuildStepList *parent, const QVariantMap &map) const
{
- if (parent->id() != ProjectExplorer::Constants::BUILDSTEPS_DEPLOY)
+ if (parent->id() != ProjectExplorer::Constants::BUILDSTEPS_BUILD)
return false;
- if (!AndroidManager::supportsAndroid(parent->target()))
+ if (!Android::AndroidManager::supportsAndroid(parent->target()))
return false;
if (parent->contains(AndroidPackageInstallationStep::Id))
return false;
@@ -89,7 +88,7 @@ bool AndroidPackageInstallationFactory::canRestore(BuildStepList *parent, const
BuildStep *AndroidPackageInstallationFactory::restore(BuildStepList *parent, const QVariantMap &map)
{
Q_ASSERT(canRestore(parent, map));
- AndroidPackageInstallationStep * const step = new AndroidPackageInstallationStep(AndroidPackageInstallationStep::ProjectDirectory, parent);
+ AndroidPackageInstallationStep * const step = new AndroidPackageInstallationStep(parent);
if (!step->fromMap(map)) {
delete step;
return 0;
diff --git a/src/plugins/android/androidpackageinstallationfactory.h b/src/plugins/qmakeprojectmanager/androidpackageinstallationfactory.h
index b2ea80f89f..0202819f18 100644
--- a/src/plugins/android/androidpackageinstallationfactory.h
+++ b/src/plugins/qmakeprojectmanager/androidpackageinstallationfactory.h
@@ -32,7 +32,7 @@
#include <projectexplorer/buildstep.h>
-namespace Android {
+namespace QmakeProjectManager {
namespace Internal {
class AndroidPackageInstallationFactory: public ProjectExplorer::IBuildStepFactory
diff --git a/src/plugins/android/androidpackageinstallationstep.cpp b/src/plugins/qmakeprojectmanager/androidpackageinstallationstep.cpp
index a3e0f34ac6..55d5e05860 100644
--- a/src/plugins/android/androidpackageinstallationstep.cpp
+++ b/src/plugins/qmakeprojectmanager/androidpackageinstallationstep.cpp
@@ -28,8 +28,8 @@
****************************************************************************/
#include "androidpackageinstallationstep.h"
-#include "androidmanager.h"
-#include "androidconstants.h"
+
+#include <android/androidconstants.h>
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/target.h>
@@ -38,19 +38,19 @@
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/gnumakeparser.h>
#include <utils/hostosinfo.h>
-#include <qmakeprojectmanager/qmakeparser.h>
#include <QDir>
-using namespace Android::Internal;
+using namespace Android;
+using namespace QmakeProjectManager::Internal;
const Core::Id AndroidPackageInstallationStep::Id = Core::Id("Qt4ProjectManager.AndroidPackageInstallationStep");
namespace {
const char ANDROIDDIRECTORY[] = "Android.AndroidPackageInstallationStep.AndroidDirectory";
}
-AndroidPackageInstallationStep::AndroidPackageInstallationStep(AndroidDirectory mode,ProjectExplorer::BuildStepList *bsl)
- : AbstractProcessStep(bsl, Id), m_androidDirectory(mode)
+AndroidPackageInstallationStep::AndroidPackageInstallationStep(ProjectExplorer::BuildStepList *bsl)
+ : AbstractProcessStep(bsl, Id)
{
const QString name = tr("Copy application data");
setDefaultDisplayName(name);
@@ -64,13 +64,7 @@ AndroidPackageInstallationStep::AndroidPackageInstallationStep(ProjectExplorer::
bool AndroidPackageInstallationStep::init()
{
ProjectExplorer::BuildConfiguration *bc = buildConfiguration();
- if (!bc)
- bc = target()->activeBuildConfiguration();
- QString dirPath;
- if (m_androidDirectory == ProjectDirectory)
- dirPath = AndroidManager::dirPath(target()).toString();
- else
- dirPath = bc->buildDirectory().appendPath(QLatin1String(Constants::ANDROID_BUILDDIRECTORY)).toString();
+ QString dirPath = bc->buildDirectory().appendPath(QLatin1String(Constants::ANDROID_BUILDDIRECTORY)).toString();
if (Utils::HostOsInfo::isWindowsHost())
if (bc->environment().searchInPath(QLatin1String("sh.exe")).isEmpty())
dirPath = QDir::toNativeSeparators(dirPath);
@@ -95,19 +89,11 @@ bool AndroidPackageInstallationStep::init()
appendOutputParser(parser);
outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory());
- m_androidDirToClean = m_androidDirectory == BuildDirectory ? dirPath : QString();
+ m_androidDirToClean = dirPath;
return AbstractProcessStep::init();
}
-bool AndroidPackageInstallationStep::fromMap(const QVariantMap &map)
-{
- if (!AbstractProcessStep::fromMap(map))
- return false;
- m_androidDirectory = AndroidDirectory(map.value(QLatin1String(ANDROIDDIRECTORY)).toInt());
- return true;
-}
-
void AndroidPackageInstallationStep::run(QFutureInterface<bool> &fi)
{
QString error;
@@ -124,13 +110,6 @@ void AndroidPackageInstallationStep::run(QFutureInterface<bool> &fi)
AbstractProcessStep::run(fi);
}
-QVariantMap AndroidPackageInstallationStep::toMap() const
-{
- QVariantMap map = AbstractProcessStep::toMap();
- map.insert(QLatin1String(ANDROIDDIRECTORY), m_androidDirectory);
- return map;
-}
-
ProjectExplorer::BuildStepConfigWidget *AndroidPackageInstallationStep::createConfigWidget()
{
return new AndroidPackageInstallationStepWidget(this);
diff --git a/src/plugins/android/androidpackageinstallationstep.h b/src/plugins/qmakeprojectmanager/androidpackageinstallationstep.h
index dd61729925..7d439aa965 100644
--- a/src/plugins/android/androidpackageinstallationstep.h
+++ b/src/plugins/qmakeprojectmanager/androidpackageinstallationstep.h
@@ -33,7 +33,7 @@
#include <projectexplorer/buildstep.h>
#include <projectexplorer/abstractprocessstep.h>
-namespace Android {
+namespace QmakeProjectManager {
namespace Internal {
class AndroidPackageInstallationStep : public ProjectExplorer::AbstractProcessStep
@@ -42,13 +42,9 @@ class AndroidPackageInstallationStep : public ProjectExplorer::AbstractProcessSt
friend class AndroidPackageInstallationFactory;
public:
- enum AndroidDirectory { ProjectDirectory, BuildDirectory };
- explicit AndroidPackageInstallationStep(AndroidDirectory mode, ProjectExplorer::BuildStepList *bsl);
+ explicit AndroidPackageInstallationStep(ProjectExplorer::BuildStepList *bsl);
bool init();
- bool fromMap(const QVariantMap &map);
- QVariantMap toMap() const;
-
ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
bool immutable() const;
@@ -56,7 +52,6 @@ public:
private:
AndroidPackageInstallationStep(ProjectExplorer::BuildStepList *bc,
AndroidPackageInstallationStep *other);
- AndroidDirectory m_androidDirectory;
QString m_androidDirToClean;
static const Core::Id Id;
};
diff --git a/src/plugins/android/qmakeandroidsupport.cpp b/src/plugins/qmakeprojectmanager/androidqmakebuildconfigurationfactory.cpp
index 5c25ecfbae..4cbaa63ab8 100644
--- a/src/plugins/android/qmakeandroidsupport.cpp
+++ b/src/plugins/qmakeprojectmanager/androidqmakebuildconfigurationfactory.cpp
@@ -1,6 +1,6 @@
-/**************************************************************************
+/****************************************************************************
**
-** Copyright (c) 2014 BogDan Vatra <bog_dan_ro@yahoo.com>
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
@@ -27,49 +27,45 @@
**
****************************************************************************/
-#include "qmakeandroidsupport.h"
-
-#include "androidconstants.h"
+#include "androidqmakebuildconfigurationfactory.h"
+#include "qmakeandroidbuildapkstep.h"
#include "androidpackageinstallationstep.h"
-#include <projectexplorer/buildmanager.h>
+#include <android/androidmanager.h>
#include <projectexplorer/buildsteplist.h>
-#include <projectexplorer/deployconfiguration.h>
-#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorerconstants.h>
-#include <projectexplorer/target.h>
-#include <qtsupport/qtkitinformation.h>
-
-#include <qmakeprojectmanager/qmakebuildconfiguration.h>
-#include <qmakeprojectmanager/qmakenodes.h>
-#include <qmakeprojectmanager/qmakeproject.h>
-#include <qmakeprojectmanager/qmakestep.h>
-using namespace QmakeProjectManager; // The class will eventually be moved there anyway
+using namespace QmakeProjectManager;
+using namespace QmakeProjectManager::Internal;
-namespace Android {
-namespace Internal {
-bool QmakeAndroidSupport::canHandle(const ProjectExplorer::Target *target) const
+int AndroidQmakeBuildConfigurationFactory::priority(const ProjectExplorer::Kit *k, const QString &projectPath) const
{
- return qobject_cast<QmakeProject*>(target->project());
+ if (QmakeBuildConfigurationFactory::priority(k, projectPath) >= 0
+ && Android::AndroidManager::supportsAndroid(k))
+ return 1;
+ return -1;
}
-QStringList QmakeAndroidSupport::soLibSearchPath(const ProjectExplorer::Target *target) const
+int AndroidQmakeBuildConfigurationFactory::priority(const ProjectExplorer::Target *parent) const
{
- QStringList res;
- QmakeBuildConfiguration *bc = qobject_cast<QmakeBuildConfiguration*>(target->activeBuildConfiguration());
- QmakeProject *project = qobject_cast<QmakeProject*>(target->project());
- Q_ASSERT(project);
- if (!project)
- return res;
+ if (QmakeBuildConfigurationFactory::priority(parent) >= 0
+ && Android::AndroidManager::supportsAndroid(parent))
+ return 1;
+ return -1;
+}
- foreach (QmakeProFileNode *node, project->allProFiles()) {
- res << node->buildDir(bc);
- }
+ProjectExplorer::BuildConfiguration *AndroidQmakeBuildConfigurationFactory::create(ProjectExplorer::Target *parent, const ProjectExplorer::BuildInfo *info) const
+{
+ ProjectExplorer::BuildConfiguration *bc = QmakeBuildConfigurationFactory::create(parent, info);
+ ProjectExplorer::BuildStepList *buildSteps = bc->stepList(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_BUILD));
+ buildSteps->insertStep(2, new AndroidPackageInstallationStep(buildSteps));
+ buildSteps->insertStep(3, new QmakeAndroidBuildApkStep(buildSteps));
- return res;
+ return bc;
}
-} // namespace Internal
-} // namespace Android
+// should the buildconfiguration have its own id?
+// and implement restore/clone then?
+
+
diff --git a/src/plugins/qmakeprojectmanager/androidqmakebuildconfigurationfactory.h b/src/plugins/qmakeprojectmanager/androidqmakebuildconfigurationfactory.h
new file mode 100644
index 0000000000..4625024538
--- /dev/null
+++ b/src/plugins/qmakeprojectmanager/androidqmakebuildconfigurationfactory.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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.
+**
+****************************************************************************/
+
+#ifndef ANDROIDQMAKEBUILDCONFIGURATIONFACTORY_H
+#define ANDROIDQMAKEBUILDCONFIGURATIONFACTORY_H
+
+#include "qmakebuildconfiguration.h"
+
+namespace QmakeProjectManager {
+namespace Internal {
+
+
+class AndroidQmakeBuildConfigurationFactory : public QmakeBuildConfigurationFactory
+{
+public:
+ explicit AndroidQmakeBuildConfigurationFactory(QObject *parent = 0)
+ : QmakeBuildConfigurationFactory(parent)
+ { }
+
+ int priority(const ProjectExplorer::Kit *k, const QString &projectPath) const;
+ int priority(const ProjectExplorer::Target *parent) const;
+
+ ProjectExplorer::BuildConfiguration *create(ProjectExplorer::Target *parent,
+ const ProjectExplorer::BuildInfo *info) const;
+ // The clone and restore from QmakeBuildConfigurationFactory
+ // work for us too.
+};
+
+} // namespace Internal
+} // namespace QmakeProjectManager
+
+
+#endif // ANDROIDQMAKEBUILDCONFIGURATIONFACTORY_H
diff --git a/src/plugins/android/createandroidmanifestwizard.cpp b/src/plugins/qmakeprojectmanager/createandroidmanifestwizard.cpp
index fffe8e5e5b..180616037d 100644
--- a/src/plugins/android/createandroidmanifestwizard.cpp
+++ b/src/plugins/qmakeprojectmanager/createandroidmanifestwizard.cpp
@@ -29,21 +29,31 @@
#include "createandroidmanifestwizard.h"
+#include <android/androidmanager.h>
+#include <android/androidqtsupport.h>
+
+#include <coreplugin/editormanager/editormanager.h>
+#include <coreplugin/coreconstants.h>
+
#include <projectexplorer/target.h>
+
#include <qmakeprojectmanager/qmakeproject.h>
#include <qmakeprojectmanager/qmakenodes.h>
+
#include <proparser/prowriter.h>
+
+#include <qtsupport/qtkitinformation.h>
+
#include <QComboBox>
#include <QFormLayout>
#include <QLabel>
#include <QMessageBox>
#include <QVBoxLayout>
-#include <qtsupport/qtkitinformation.h>
-#include <coreplugin/coreconstants.h>
-#include <coreplugin/editormanager/editormanager.h>
using namespace Android;
-using namespace Android::Internal;
+using namespace QmakeProjectManager;
+using namespace QmakeProjectManager::Internal;
+
using QmakeProjectManager::QmakeProject;
using QmakeProjectManager::QmakeProFileNode;
diff --git a/src/plugins/android/createandroidmanifestwizard.h b/src/plugins/qmakeprojectmanager/createandroidmanifestwizard.h
index 8cb8c95b7f..e084782c13 100644
--- a/src/plugins/android/createandroidmanifestwizard.h
+++ b/src/plugins/qmakeprojectmanager/createandroidmanifestwizard.h
@@ -40,7 +40,7 @@ QT_END_NAMESPACE
namespace ProjectExplorer { class Target; }
namespace QmakeProjectManager { class QmakeProFileNode; }
-namespace Android {
+namespace QmakeProjectManager {
namespace Internal {
class CreateAndroidManifestWizard;
@@ -104,7 +104,8 @@ private:
QmakeProjectManager::QmakeProFileNode *m_node;
QString m_directory;
};
-}
-}
+
+} //namespace QmakeProjectManager
+} //namespace Internal
#endif // CREATEANDROIDMANIFESTWIZARD_H
diff --git a/src/plugins/qmakeprojectmanager/qmakeandroidbuildapkstep.cpp b/src/plugins/qmakeprojectmanager/qmakeandroidbuildapkstep.cpp
new file mode 100644
index 0000000000..1848a6536b
--- /dev/null
+++ b/src/plugins/qmakeprojectmanager/qmakeandroidbuildapkstep.cpp
@@ -0,0 +1,293 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 BogDan Vatra <bog_dan_ro@yahoo.com>
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 "qmakeandroidbuildapkstep.h"
+#include "qmakeandroidbuildapkwidget.h"
+#include "qmakenodes.h"
+#include "qmakeproject.h"
+
+#include <android/androidconfigurations.h>
+#include <android/androidconstants.h>
+#include <android/androidmanager.h>
+#include <android/androidqtsupport.h>
+
+#include <projectexplorer/buildconfiguration.h>
+#include <projectexplorer/buildsteplist.h>
+#include <projectexplorer/project.h>
+#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/target.h>
+
+#include <qtsupport/qtkitinformation.h>
+
+#include <utils/qtcprocess.h>
+
+#include <QHBoxLayout>
+
+using namespace Android;
+
+namespace QmakeProjectManager {
+namespace Internal {
+
+const Core::Id ANDROID_BUILD_APK_ID("QmakeProjectManager.AndroidBuildApkStep");
+const QLatin1String ProFilePathForInputFile("ProFilePathForInputFile");
+
+
+//////////////////
+// QmakeAndroidBuildApkStepFactory
+/////////////////
+
+QmakeAndroidBuildApkStepFactory::QmakeAndroidBuildApkStepFactory(QObject *parent)
+ : IBuildStepFactory(parent)
+{
+}
+
+QList<Core::Id> QmakeAndroidBuildApkStepFactory::availableCreationIds(ProjectExplorer::BuildStepList *parent) const
+{
+ if (parent->id() != ProjectExplorer::Constants::BUILDSTEPS_BUILD
+ || !canHandle(parent->target())
+ || parent->contains(ANDROID_BUILD_APK_ID)) {
+ return QList<Core::Id>();
+ }
+
+ return QList<Core::Id>() << ANDROID_BUILD_APK_ID;
+}
+
+QString QmakeAndroidBuildApkStepFactory::displayNameForId(const Core::Id id) const
+{
+ if (id == ANDROID_BUILD_APK_ID)
+ return tr("Build Android APK");
+ return QString();
+}
+
+bool QmakeAndroidBuildApkStepFactory::canCreate(ProjectExplorer::BuildStepList *parent, const Core::Id id) const
+{
+ return availableCreationIds(parent).contains(id);
+}
+
+ProjectExplorer::BuildStep *QmakeAndroidBuildApkStepFactory::create(ProjectExplorer::BuildStepList *parent, const Core::Id id)
+{
+ Q_ASSERT(canCreate(parent, id));
+ Q_UNUSED(id);
+ return new QmakeAndroidBuildApkStep(parent);
+}
+
+bool QmakeAndroidBuildApkStepFactory::canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const
+{
+ return canCreate(parent, ProjectExplorer::idFromMap(map));
+}
+
+ProjectExplorer::BuildStep *QmakeAndroidBuildApkStepFactory::restore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map)
+{
+ Q_ASSERT(canRestore(parent, map));
+ QmakeAndroidBuildApkStep * const step = new QmakeAndroidBuildApkStep(parent);
+ if (!step->fromMap(map)) {
+ delete step;
+ return 0;
+ }
+ return step;
+}
+
+bool QmakeAndroidBuildApkStepFactory::canClone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *product) const
+{
+ return canCreate(parent, product->id());
+}
+
+ProjectExplorer::BuildStep *QmakeAndroidBuildApkStepFactory::clone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *product)
+{
+ Q_ASSERT(canClone(parent, product));
+ return new QmakeAndroidBuildApkStep(parent, static_cast<QmakeAndroidBuildApkStep *>(product));
+}
+
+bool QmakeAndroidBuildApkStepFactory::canHandle(ProjectExplorer::Target *t) const
+{
+ return t->project()->supportsKit(t->kit())
+ && AndroidManager::supportsAndroid(t)
+ && qobject_cast<QmakeProject *>(t->project());
+}
+
+
+QmakeAndroidBuildApkStep::QmakeAndroidBuildApkStep(ProjectExplorer::BuildStepList *bc)
+ :Android::AndroidBuildApkStep(bc, ANDROID_BUILD_APK_ID)
+{
+ ctor();
+}
+
+QString QmakeAndroidBuildApkStep::proFilePathForInputFile() const
+{
+ return m_proFilePathForInputFile;
+}
+
+void QmakeAndroidBuildApkStep::setProFilePathForInputFile(const QString &path)
+{
+ m_proFilePathForInputFile = path;
+}
+
+QmakeAndroidBuildApkStep::QmakeAndroidBuildApkStep(ProjectExplorer::BuildStepList *bc, QmakeAndroidBuildApkStep *other)
+ : Android::AndroidBuildApkStep(bc, other),
+ m_proFilePathForInputFile(other->m_proFilePathForInputFile)
+{
+ ctor();
+}
+
+Utils::FileName QmakeAndroidBuildApkStep::androidPackageSourceDir() const
+{
+ QmakeProjectManager::QmakeProject *pro = static_cast<QmakeProjectManager::QmakeProject *>(project());
+ const QmakeProjectManager::QmakeProFileNode *node
+ = pro->rootQmakeProjectNode()->findProFileFor(m_proFilePathForInputFile);
+ if (!node)
+ return Utils::FileName();
+ return Utils::FileName::fromString(node->singleVariableValue(QmakeProjectManager::AndroidPackageSourceDir));
+}
+
+void QmakeAndroidBuildApkStep::ctor()
+{
+ connect(project(), SIGNAL(proFilesEvaluated()),
+ this, SLOT(updateInputFile()));
+}
+
+bool QmakeAndroidBuildApkStep::init()
+{
+ if (AndroidManager::checkForQt51Files(project()->projectDirectory()))
+ emit addOutput(tr("Found old folder \"android\" in source directory. Qt 5.2 does not use that folder by default."), ErrorOutput);
+
+ if (!Android::AndroidBuildApkStep::init())
+ return false;
+
+ QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit());
+ if (!version)
+ return false;
+
+ QString command = version->qmakeProperty("QT_HOST_BINS");
+ if (!command.endsWith(QLatin1Char('/')))
+ command += QLatin1Char('/');
+ command += QLatin1String("androiddeployqt");
+ if (Utils::HostOsInfo::isWindowsHost())
+ command += QLatin1String(".exe");
+
+ QString deploymentMethod;
+ if (m_deployAction == MinistroDeployment)
+ deploymentMethod = QLatin1String("ministro");
+ else if (m_deployAction == DebugDeployment)
+ deploymentMethod = QLatin1String("debug");
+ else if (m_deployAction == BundleLibrariesDeployment)
+ deploymentMethod = QLatin1String("bundled");
+
+ ProjectExplorer::BuildConfiguration *bc = buildConfiguration();
+ QString outputDir = bc->buildDirectory().appendPath(QLatin1String(Constants::ANDROID_BUILDDIRECTORY)).toString();
+
+ const auto *pro = static_cast<QmakeProjectManager::QmakeProject *>(project());
+ const QmakeProjectManager::QmakeProFileNode *node = pro->rootQmakeProjectNode()->findProFileFor(m_proFilePathForInputFile);
+ if (!node) { // should never happen
+ emit addOutput(tr("Internal Error: Could not find .pro file."), BuildStep::ErrorMessageOutput);
+ return false;
+ }
+
+ QString inputFile = node->singleVariableValue(QmakeProjectManager::AndroidDeploySettingsFile);
+ if (inputFile.isEmpty()) { // should never happen
+ emit addOutput(tr("Internal Error: Unknown Android deployment JSON file location."), BuildStep::ErrorMessageOutput);
+ return false;
+ }
+
+ QStringList arguments;
+ arguments << QLatin1String("--input")
+ << inputFile
+ << QLatin1String("--output")
+ << outputDir
+ << QLatin1String("--deployment")
+ << deploymentMethod
+ << QLatin1String("--ant")
+ << AndroidConfigurations::currentConfig().antToolPath().toString()
+ << QLatin1String("--android-platform")
+ << AndroidManager::buildTargetSDK(target())
+ << QLatin1String("--jdk")
+ << AndroidConfigurations::currentConfig().openJDKLocation().toString();
+
+ if (m_verbose)
+ arguments << QLatin1String("--verbose");
+
+ if (m_signPackage) {
+ arguments << QLatin1String("--sign")
+ << m_keystorePath.toString()
+ << m_certificateAlias
+ << QLatin1String("--storepass")
+ << m_keystorePasswd;
+ if (!m_certificatePasswd.isEmpty())
+ arguments << QLatin1String("--keypass")
+ << m_certificatePasswd;
+ }
+
+ ProjectExplorer::ProcessParameters *pp = processParameters();
+ pp->setMacroExpander(bc->macroExpander());
+ pp->setWorkingDirectory(bc->buildDirectory().toString());
+ Utils::Environment env = bc->environment();
+ pp->setEnvironment(env);
+ pp->setCommand(command);
+ pp->setArguments(Utils::QtcProcess::joinArgs(arguments));
+ pp->resolveAll();
+
+ return true;
+}
+
+ProjectExplorer::BuildStepConfigWidget *QmakeAndroidBuildApkStep::createConfigWidget()
+{
+ return new QmakeAndroidBuildApkWidget(this);
+}
+
+bool QmakeAndroidBuildApkStep::fromMap(const QVariantMap &map)
+{
+ m_proFilePathForInputFile = map.value(ProFilePathForInputFile).toString();
+ return Android::AndroidBuildApkStep::fromMap(map);
+}
+
+QVariantMap QmakeAndroidBuildApkStep::toMap() const
+{
+ QVariantMap map = Android::AndroidBuildApkStep::toMap();
+ map.insert(ProFilePathForInputFile, m_proFilePathForInputFile);
+ return map;
+}
+
+void QmakeAndroidBuildApkStep::updateInputFile()
+{
+ QmakeProject *pro = static_cast<QmakeProject *>(project());
+ QList<QmakeProFileNode *> nodes = pro->applicationProFiles();
+
+ const QmakeProFileNode *node = pro->rootQmakeProjectNode()->findProFileFor(m_proFilePathForInputFile);
+ if (!nodes.contains(const_cast<QmakeProFileNode *>(node))) {
+ if (!nodes.isEmpty())
+ m_proFilePathForInputFile = nodes.first()->path();
+ else
+ m_proFilePathForInputFile.clear();
+ }
+
+ emit inputFileChanged();
+}
+
+} // namespace Internal
+} // namespace QmakeProjectManager
diff --git a/src/plugins/qmakeprojectmanager/qmakeandroidbuildapkstep.h b/src/plugins/qmakeprojectmanager/qmakeandroidbuildapkstep.h
new file mode 100644
index 0000000000..3a25c3bf04
--- /dev/null
+++ b/src/plugins/qmakeprojectmanager/qmakeandroidbuildapkstep.h
@@ -0,0 +1,101 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 BogDan Vatra <bog_dan_ro@yahoo.com>
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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.
+**
+****************************************************************************/
+
+#ifndef QMAKEANDROIDBUILDAPKSTEP_H
+#define QMAKEANDROIDBUILDAPKSTEP_H
+
+#include <android/androidbuildapkstep.h>
+
+namespace QmakeProjectManager {
+namespace Internal {
+
+
+class QmakeAndroidBuildApkStepFactory : public ProjectExplorer::IBuildStepFactory
+{
+ Q_OBJECT
+public:
+ explicit QmakeAndroidBuildApkStepFactory(QObject *parent = 0);
+
+ QList<Core::Id> availableCreationIds(ProjectExplorer::BuildStepList *parent) const;
+ QString displayNameForId(const Core::Id id) const;
+
+ bool canCreate(ProjectExplorer::BuildStepList *parent,
+ const Core::Id id) const;
+ ProjectExplorer::BuildStep *create(ProjectExplorer::BuildStepList *parent, const Core::Id id);
+
+ bool canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const;
+ ProjectExplorer::BuildStep *restore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map);
+
+ bool canClone(ProjectExplorer::BuildStepList *parent,
+ ProjectExplorer::BuildStep *product) const;
+ ProjectExplorer::BuildStep *clone(ProjectExplorer::BuildStepList *parent,
+ ProjectExplorer::BuildStep *product);
+private:
+ bool canHandle(ProjectExplorer::Target *t) const;
+
+};
+
+class QmakeAndroidBuildApkStep : public Android::AndroidBuildApkStep
+{
+ Q_OBJECT
+public:
+ QmakeAndroidBuildApkStep(ProjectExplorer::BuildStepList *bc);
+ QString proFilePathForInputFile() const;
+ void setProFilePathForInputFile(const QString &path);
+
+protected:
+ friend class QmakeAndroidBuildApkStepFactory;
+ QmakeAndroidBuildApkStep(ProjectExplorer::BuildStepList *bc,
+ QmakeAndroidBuildApkStep *other);
+
+ Utils::FileName androidPackageSourceDir() const;
+
+protected:
+ void ctor();
+ bool init();
+ ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
+ bool fromMap(const QVariantMap &map);
+ QVariantMap toMap() const;
+
+signals:
+ // also on purpose emitted if the possible values of this changed
+ void inputFileChanged();
+
+private slots:
+ void updateInputFile();
+
+private:
+ QString m_proFilePathForInputFile;
+};
+
+} // namespace Internal
+} // namespace QmakeProjectManager
+
+#endif // QMAKEANDROIDBUILDAPKSTEP_H
diff --git a/src/plugins/qmakeprojectmanager/qmakeandroidbuildapkwidget.cpp b/src/plugins/qmakeprojectmanager/qmakeandroidbuildapkwidget.cpp
new file mode 100644
index 0000000000..c6844891f2
--- /dev/null
+++ b/src/plugins/qmakeprojectmanager/qmakeandroidbuildapkwidget.cpp
@@ -0,0 +1,190 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 BogDan Vatra <bog_dan_ro@yahoo.com>
+** Contact: http://www.qt-project.org/legal
+**
+** 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 "createandroidmanifestwizard.h"
+#include "qmakeandroidbuildapkstep.h"
+#include "qmakeandroidbuildapkwidget.h"
+#include "qmakenodes.h"
+#include "qmakeproject.h"
+#include "ui_qmakeandroidbuildapkwidget.h"
+
+#include <android/androidbuildapkwidget.h>
+#include <android/androidmanager.h>
+
+#include <QFileDialog>
+
+namespace QmakeProjectManager {
+namespace Internal {
+
+QmakeAndroidBuildApkWidget::QmakeAndroidBuildApkWidget(QmakeAndroidBuildApkStep *step) :
+ ProjectExplorer::BuildStepConfigWidget(),
+ m_ui(new Ui::QmakeAndroidBuildApkWidget),
+ m_step(step),
+ m_extraLibraryListModel(0),
+ m_ignoreChange(false)
+{
+ QVBoxLayout *topLayout = new QVBoxLayout;
+
+ QHBoxLayout *qt51WarningLayout = new QHBoxLayout();
+ QLabel *oldFilesWarningIcon = new QLabel(this);
+ oldFilesWarningIcon->setObjectName(QStringLiteral("oldFilesWarningIcon"));
+ QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
+ sizePolicy.setHorizontalStretch(0);
+ sizePolicy.setVerticalStretch(0);
+ sizePolicy.setHeightForWidth(oldFilesWarningIcon->sizePolicy().hasHeightForWidth());
+ oldFilesWarningIcon->setSizePolicy(sizePolicy);
+ oldFilesWarningIcon->setPixmap(QPixmap(QLatin1String(":/core/images/warning.png")));
+ oldFilesWarningIcon->setAlignment(Qt::Alignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop));
+ qt51WarningLayout->addWidget(oldFilesWarningIcon);
+
+ QLabel *oldFilesWarningLabel = new QLabel(this);
+ oldFilesWarningLabel->setObjectName(QStringLiteral("oldFilesWarningLabel"));
+ oldFilesWarningLabel->setWordWrap(true);
+ qt51WarningLayout->addWidget(oldFilesWarningLabel);
+
+ topLayout->addWidget(new Android::AndroidBuildApkWidget(step));
+
+ QWidget *widget = new QWidget(this);
+ m_ui->setupUi(widget);
+ topLayout->addWidget(widget);
+ setLayout(topLayout);
+
+ bool oldFiles = Android::AndroidManager::checkForQt51Files(m_step->project()->projectDirectory());
+ oldFilesWarningIcon->setVisible(oldFiles);
+ oldFilesWarningLabel->setVisible(oldFiles);
+
+ m_extraLibraryListModel = new AndroidExtraLibraryListModel(static_cast<QmakeProject *>(m_step->project()), this);
+ m_ui->androidExtraLibsListView->setModel(m_extraLibraryListModel);
+
+ updateInputFileUi();
+ connect(m_step, SIGNAL(inputFileChanged()),
+ SLOT(updateInputFileUi()));
+
+ connect(m_ui->inputFileComboBox, SIGNAL(currentIndexChanged(int)),
+ SLOT(inputFileComboBoxIndexChanged()));
+
+ connect(m_ui->createAndroidManifestButton, SIGNAL(clicked()),
+ SLOT(createManifestButton()));
+
+ connect(m_ui->addAndroidExtraLibButton, SIGNAL(clicked()),
+ SLOT(addAndroidExtraLib()));
+
+ connect(m_ui->removeAndroidExtraLibButton, SIGNAL(clicked()),
+ SLOT(removeAndroidExtraLib()));
+
+ connect(m_ui->androidExtraLibsListView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ SLOT(checkEnableRemoveButton()));
+
+ connect(m_extraLibraryListModel, SIGNAL(enabledChanged(bool)),
+ m_ui->additionalLibrariesGroupBox, SLOT(setEnabled(bool)));
+
+ m_ui->additionalLibrariesGroupBox->setEnabled(m_extraLibraryListModel->isEnabled());
+}
+
+QmakeAndroidBuildApkWidget::~QmakeAndroidBuildApkWidget()
+{
+ delete m_ui;
+}
+
+void QmakeAndroidBuildApkWidget::updateInputFileUi()
+{
+ QmakeProject *project
+ = static_cast<QmakeProject *>(m_step->project());
+ QList<QmakeProFileNode *> nodes = project->applicationProFiles();
+ int size = nodes.size();
+ if (size == 0 || size == 1) {
+ // there's nothing to select, e.g. before parsing
+ m_ui->inputFileLabel->setVisible(false);
+ m_ui->inputFileComboBox->setVisible(false);
+ } else {
+ m_ignoreChange = true;
+ m_ui->inputFileLabel->setVisible(true);
+ m_ui->inputFileComboBox->setVisible(true);
+
+ m_ui->inputFileComboBox->clear();
+ foreach (QmakeProFileNode *node, nodes)
+ m_ui->inputFileComboBox->addItem(node->displayName(), node->path());
+
+ int index = m_ui->inputFileComboBox->findData(m_step->proFilePathForInputFile());
+ m_ui->inputFileComboBox->setCurrentIndex(index);
+ m_ignoreChange = false;
+ }
+}
+
+void QmakeAndroidBuildApkWidget::inputFileComboBoxIndexChanged()
+{
+ if (m_ignoreChange)
+ return;
+
+ QString proFilePath = m_ui->inputFileComboBox->itemData(m_ui->inputFileComboBox->currentIndex()).toString();
+ m_step->setProFilePathForInputFile(proFilePath);
+}
+
+void QmakeAndroidBuildApkWidget::createManifestButton()
+{
+ CreateAndroidManifestWizard wizard(m_step->target());
+ wizard.exec();
+}
+
+void QmakeAndroidBuildApkWidget::addAndroidExtraLib()
+{
+ QStringList fileNames = QFileDialog::getOpenFileNames(this,
+ tr("Select additional libraries"),
+ QDir::homePath(),
+ tr("Libraries (*.so)"));
+
+ if (!fileNames.isEmpty())
+ m_extraLibraryListModel->addEntries(fileNames);
+}
+
+void QmakeAndroidBuildApkWidget::removeAndroidExtraLib()
+{
+ QModelIndexList removeList = m_ui->androidExtraLibsListView->selectionModel()->selectedIndexes();
+ m_extraLibraryListModel->removeEntries(removeList);
+}
+
+void QmakeAndroidBuildApkWidget::checkEnableRemoveButton()
+{
+ m_ui->removeAndroidExtraLibButton->setEnabled(m_ui->androidExtraLibsListView->selectionModel()->hasSelection());
+}
+
+QString QmakeAndroidBuildApkWidget::summaryText() const
+{
+ return tr("<b>Build Android APK</b>");
+}
+
+QString QmakeAndroidBuildApkWidget::displayName() const
+{
+ return summaryText();
+}
+
+} // namespace Internal
+} // namespace QmakeProjectManager
+
+
diff --git a/src/plugins/qmakeprojectmanager/qmakeandroidbuildapkwidget.h b/src/plugins/qmakeprojectmanager/qmakeandroidbuildapkwidget.h
new file mode 100644
index 0000000000..f21db18d88
--- /dev/null
+++ b/src/plugins/qmakeprojectmanager/qmakeandroidbuildapkwidget.h
@@ -0,0 +1,85 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 BogDan Vatra <bog_dan_ro@yahoo.com>
+** Contact: http://www.qt-project.org/legal
+**
+** 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.
+**
+****************************************************************************/
+
+#ifndef QMAKEANDROIDBUILDAPKWIDGET_H
+#define QMAKEANDROIDBUILDAPKWIDGET_H
+
+#include "androidextralibrarylistmodel.h"
+
+#include <QWidget>
+
+#include <projectexplorer/buildstep.h>
+
+QT_BEGIN_NAMESPACE
+class QLabel;
+QT_END_NAMESPACE
+
+namespace QmakeProjectManager {
+class QmakeBuildConfiguration;
+
+namespace Internal {
+
+namespace Ui {
+class QmakeAndroidBuildApkWidget;
+}
+
+class QmakeAndroidBuildApkStep;
+
+class QmakeAndroidBuildApkWidget : public ProjectExplorer::BuildStepConfigWidget
+{
+ Q_OBJECT
+
+public:
+ explicit QmakeAndroidBuildApkWidget(QmakeAndroidBuildApkStep *step);
+ ~QmakeAndroidBuildApkWidget();
+
+private slots:
+ void updateInputFileUi();
+ void inputFileComboBoxIndexChanged();
+ void createManifestButton();
+ void addAndroidExtraLib();
+ void removeAndroidExtraLib();
+ void checkEnableRemoveButton();
+
+private:
+ Ui::QmakeAndroidBuildApkWidget *m_ui;
+ QmakeAndroidBuildApkStep *m_step;
+ AndroidExtraLibraryListModel *m_extraLibraryListModel;
+ bool m_ignoreChange;
+
+ // BuildStepConfigWidget interface
+public:
+ QString summaryText() const;
+ QString displayName() const;
+};
+
+} // namespace Internal
+} // namespace QmakeProjectManager
+
+#endif // QMAKEANDROIDBUILDAPKWIDGET_H
diff --git a/src/plugins/qmakeprojectmanager/qmakeandroidbuildapkwidget.ui b/src/plugins/qmakeprojectmanager/qmakeandroidbuildapkwidget.ui
new file mode 100644
index 0000000000..c92178da0f
--- /dev/null
+++ b/src/plugins/qmakeprojectmanager/qmakeandroidbuildapkwidget.ui
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QmakeProjectManager::Internal::QmakeAndroidBuildApkWidget</class>
+ <widget class="QWidget" name="QmakeProjectManager::Internal::QmakeAndroidBuildApkWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>680</width>
+ <height>435</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QGroupBox" name="additionalLibrariesGroupBox_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Android</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="createAndroidManifestButton">
+ <property name="text">
+ <string>Create AndroidManifest.xml</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="inputFileLabel">
+ <property name="text">
+ <string>Input file for androiddeployqt:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="inputFileComboBox"/>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="additionalLibrariesGroupBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Additional Libraries</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QHBoxLayout" name="androidExtraLibsLayout">
+ <item>
+ <widget class="QListView" name="androidExtraLibsListView">
+ <property name="toolTip">
+ <string>List of extra libraries to include in Android package and load on startup.</string>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::ExtendedSelection</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="androidExtraLibsButtonLayout">
+ <item>
+ <widget class="QToolButton" name="addAndroidExtraLibButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Select library to include in package.</string>
+ </property>
+ <property name="text">
+ <string>Add...</string>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextOnly</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="removeAndroidExtraLibButton">
+ <property name="toolTip">
+ <string>Remove currently selected library from list.</string>
+ </property>
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/plugins/android/qmakeandroidrunconfiguration.cpp b/src/plugins/qmakeprojectmanager/qmakeandroidrunconfiguration.cpp
index 1f5baf6c1c..83bca386d0 100644
--- a/src/plugins/android/qmakeandroidrunconfiguration.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeandroidrunconfiguration.cpp
@@ -45,7 +45,7 @@ namespace {
using namespace ProjectExplorer;
using QmakeProjectManager::QmakeProject;
-namespace Android {
+namespace QmakeProjectManager {
namespace Internal {
QmakeAndroidRunConfiguration::QmakeAndroidRunConfiguration(Target *parent, Core::Id id, const QString &path)
diff --git a/src/plugins/android/qmakeandroidrunconfiguration.h b/src/plugins/qmakeprojectmanager/qmakeandroidrunconfiguration.h
index 95fd4fbe9a..612c78957d 100644
--- a/src/plugins/android/qmakeandroidrunconfiguration.h
+++ b/src/plugins/qmakeprojectmanager/qmakeandroidrunconfiguration.h
@@ -30,11 +30,11 @@
#ifndef QMAKE_ANDROIDRUNCONFIGURATION_H
#define QMAKE_ANDROIDRUNCONFIGURATION_H
-#include "androidrunconfiguration.h"
+#include <android/androidrunconfiguration.h>
-namespace QmakeProjectManager { class QmakeProFileNode; }
+namespace QmakeProjectManager {
+class QmakeProFileNode;
-namespace Android {
namespace Internal {
class QmakeAndroidRunConfiguration : public Android::AndroidRunConfiguration
diff --git a/src/plugins/android/qmakeandroidrunfactories.cpp b/src/plugins/qmakeprojectmanager/qmakeandroidrunfactories.cpp
index d559579508..0cea9cc73b 100644
--- a/src/plugins/android/qmakeandroidrunfactories.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeandroidrunfactories.cpp
@@ -45,9 +45,8 @@
using namespace Android;
using namespace ProjectExplorer;
-using namespace QmakeProjectManager;
-namespace Android {
+namespace QmakeProjectManager {
namespace Internal {
static const char ANDROID_RC_ID_PREFIX[] = "Qt4ProjectManager.AndroidRunConfiguration:";
diff --git a/src/plugins/android/qmakeandroidrunfactories.h b/src/plugins/qmakeprojectmanager/qmakeandroidrunfactories.h
index 9286612c92..bc4a71aead 100644
--- a/src/plugins/android/qmakeandroidrunfactories.h
+++ b/src/plugins/qmakeprojectmanager/qmakeandroidrunfactories.h
@@ -41,7 +41,7 @@ class Target;
class Node;
} // namespace ProjectExplorer
-namespace Android {
+namespace QmakeProjectManager {
namespace Internal {
class QmakeAndroidRunConfigurationFactory : public ProjectExplorer::IRunConfigurationFactory
diff --git a/src/plugins/qmakeprojectmanager/qmakeandroidsupport.cpp b/src/plugins/qmakeprojectmanager/qmakeandroidsupport.cpp
new file mode 100644
index 0000000000..1267e9e3b0
--- /dev/null
+++ b/src/plugins/qmakeprojectmanager/qmakeandroidsupport.cpp
@@ -0,0 +1,133 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 BogDan Vatra <bog_dan_ro@yahoo.com>
+** Contact: http://www.qt-project.org/legal
+**
+** 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 "androidpackageinstallationstep.h"
+#include "qmakeandroidsupport.h"
+#include "qmakebuildconfiguration.h"
+#include "qmakenodes.h"
+#include "qmakeproject.h"
+#include "qmakestep.h"
+
+#include <android/androidconstants.h>
+#include <projectexplorer/buildmanager.h>
+#include <projectexplorer/buildsteplist.h>
+#include <projectexplorer/deployconfiguration.h>
+#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/target.h>
+#include <qtsupport/qtkitinformation.h>
+
+namespace QmakeProjectManager {
+namespace Internal {
+
+bool QmakeAndroidSupport::canHandle(const ProjectExplorer::Target *target) const
+{
+ return qobject_cast<QmakeProject*>(target->project());
+}
+
+QStringList QmakeAndroidSupport::soLibSearchPath(const ProjectExplorer::Target *target) const
+{
+ QStringList res;
+ QmakeBuildConfiguration *bc = qobject_cast<QmakeBuildConfiguration*>(target->activeBuildConfiguration());
+ QmakeProject *project = qobject_cast<QmakeProject*>(target->project());
+ Q_ASSERT(project);
+ if (!project)
+ return res;
+
+ foreach (QmakeProFileNode *node, project->allProFiles()) {
+ res << node->buildDir(bc);
+ }
+
+ return res;
+}
+
+QStringList QmakeAndroidSupport::projectTargetApplications(const ProjectExplorer::Target *target) const
+{
+ QStringList apps;
+ QmakeProject *qmakeProject = qobject_cast<QmakeProject *>(target->project());
+ if (!qmakeProject)
+ return apps;
+ foreach (QmakeProFileNode *proFile, qmakeProject->applicationProFiles()) {
+ if (proFile->projectType() == ApplicationTemplate) {
+ if (proFile->targetInformation().target.startsWith(QLatin1String("lib"))
+ && proFile->targetInformation().target.endsWith(QLatin1String(".so")))
+ apps << proFile->targetInformation().target.mid(3, proFile->targetInformation().target.lastIndexOf(QLatin1Char('.')) - 3);
+ else
+ apps << proFile->targetInformation().target;
+ }
+ }
+ apps.sort();
+ return apps;
+
+}
+
+Utils::FileName QmakeAndroidSupport::apkPath(ProjectExplorer::Target *target, AndroidQtSupport::BuildType buildType) const
+{
+ QString packageName = QLatin1String("QtApp");
+ QString buildTypeName;
+ if (buildType == DebugBuild)
+ buildTypeName = QLatin1String("debug");
+ else if (buildType == ReleaseBuildUnsigned)
+ buildTypeName =QLatin1String("release-unsigned");
+ else
+ buildTypeName = QLatin1String("release");
+
+ return target->activeBuildConfiguration()->buildDirectory()
+ .appendPath(QLatin1String(Android::Constants::ANDROID_BUILDDIRECTORY))
+ .appendPath(QLatin1String("bin"))
+ .appendPath(QString::fromLatin1("%1-%2.apk")
+ .arg(packageName)
+ .arg(buildTypeName));
+}
+
+void QmakeAndroidSupport::resetBuild(const ProjectExplorer::Target *target)
+{
+ QmakeBuildConfiguration *bc = qobject_cast<QmakeBuildConfiguration*>(target->activeBuildConfiguration());
+ if (!bc)
+ return;
+
+ QMakeStep *qs = bc->qmakeStep();
+ if (!qs)
+ return;
+
+ qs->setForced(true);
+
+ ProjectExplorer::BuildManager::buildList(bc->stepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN),
+ ProjectExplorer::ProjectExplorerPlugin::displayNameForStepId(ProjectExplorer::Constants::BUILDSTEPS_CLEAN));
+ ProjectExplorer::BuildManager::appendStep(qs, ProjectExplorer::ProjectExplorerPlugin::displayNameForStepId(ProjectExplorer::Constants::BUILDSTEPS_CLEAN));
+ bc->setSubNodeBuild(0);
+ // Make the buildconfiguration emit a evironmentChanged() signal
+ // TODO find a better way
+ bool use = bc->useSystemEnvironment();
+ bc->setUseSystemEnvironment(!use);
+ bc->setUseSystemEnvironment(use);
+}
+
+} // namespace Internal
+} // namespace QmakeProjectManager
diff --git a/src/plugins/android/qmakeandroidsupport.h b/src/plugins/qmakeprojectmanager/qmakeandroidsupport.h
index 65094d3727..e2439173dd 100644
--- a/src/plugins/android/qmakeandroidsupport.h
+++ b/src/plugins/qmakeprojectmanager/qmakeandroidsupport.h
@@ -30,9 +30,9 @@
#ifndef QMAKEANDROIDSUPPORT_H
#define QMAKEANDROIDSUPPORT_H
-#include "androidqtsupport.h"
+#include <android/androidqtsupport.h>
-namespace Android {
+namespace QmakeProjectManager {
namespace Internal {
class QmakeAndroidSupport : public Android::AndroidQtSupport
@@ -41,9 +41,13 @@ class QmakeAndroidSupport : public Android::AndroidQtSupport
public:
bool canHandle(const ProjectExplorer::Target *target) const;
QStringList soLibSearchPath(const ProjectExplorer::Target *target) const;
+ QStringList projectTargetApplications(const ProjectExplorer::Target *target) const;
+ Utils::FileName apkPath(ProjectExplorer::Target *target, BuildType buildType) const;
+
+ void resetBuild(const ProjectExplorer::Target *target);
};
} // namespace Internal
-} // namespace Android
+} // namespace QmakeProjectManager
#endif // QMAKEANDROIDSUPPORT_H
diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp
index a5ef01d4fd..b716816786 100644
--- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp
@@ -52,6 +52,7 @@
#include <qtsupport/qtversionmanager.h>
#include <utils/qtcassert.h>
#include <QDebug>
+#include <android/androidmanager.h>
#include <QInputDialog>
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro
index 7146c0f11b..b8295e9188 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro
@@ -5,6 +5,10 @@ DEFINES += \
QMAKEPROJECTMANAGER_LIBRARY
HEADERS += \
+ androidextralibrarylistmodel.h \
+ androidpackageinstallationfactory.h \
+ androidpackageinstallationstep.h \
+ createandroidmanifestwizard.h \
qmakebuildinfo.h \
qmakekitinformation.h \
qmakekitconfigwidget.h \
@@ -54,9 +58,19 @@ HEADERS += \
findqmakeprofiles.h \
qmakeprojectmanager_global.h \
desktopqmakerunconfiguration.h \
- profilecompletionassist.h
+ profilecompletionassist.h \
+ qmakeandroidsupport.h \
+ qmakeandroidrunconfiguration.h \
+ qmakeandroidrunfactories.h \
+ qmakeandroidbuildapkstep.h \
+ qmakeandroidbuildapkwidget.h \
+ androidqmakebuildconfigurationfactory.h
SOURCES += \
+ androidextralibrarylistmodel.cpp \
+ androidpackageinstallationfactory.cpp \
+ androidpackageinstallationstep.cpp \
+ createandroidmanifestwizard.cpp \
qmakekitconfigwidget.cpp \
qmakekitinformation.cpp \
qmakeprojectimporter.cpp \
@@ -103,13 +117,20 @@ SOURCES += \
librarydetailscontroller.cpp \
findqmakeprofiles.cpp \
desktopqmakerunconfiguration.cpp \
- profilecompletionassist.cpp
+ profilecompletionassist.cpp \
+ qmakeandroidsupport.cpp \
+ qmakeandroidrunconfiguration.cpp \
+ qmakeandroidrunfactories.cpp \
+ qmakeandroidbuildapkstep.cpp \
+ qmakeandroidbuildapkwidget.cpp \
+ androidqmakebuildconfigurationfactory.cpp
FORMS += makestep.ui \
qmakestep.ui \
qmakeprojectconfigwidget.ui \
librarydetailswidget.ui \
- wizards/testwizardpage.ui
+ wizards/testwizardpage.ui \
+ qmakeandroidbuildapkwidget.ui
RESOURCES += qmakeprojectmanager.qrc \
wizards/wizards.qrc
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs
index 564a0b75a7..5e0b7f3cb7 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs
@@ -17,6 +17,7 @@ QtcPlugin {
Depends { name: "TextEditor" }
Depends { name: "QmlJSTools" }
Depends { name: "ResourceEditor" }
+ Depends { name: "Android" }
pluginRecommends: [
"Designer"
@@ -26,6 +27,11 @@ QtcPlugin {
name: "General"
files: [
"addlibrarywizard.cpp", "addlibrarywizard.h",
+ "androidextralibrarylistmodel.cpp", "androidextralibrarylistmodel.h",
+ "androidpackageinstallationfactory.cpp", "androidpackageinstallationfactory.h",
+ "androidpackageinstallationstep.cpp", "androidpackageinstallationstep.h",
+ "androidqmakebuildconfigurationfactory.cpp", "androidqmakebuildconfigurationfactory.h",
+ "createandroidmanifestwizard.cpp", "createandroidmanifestwizard.h",
"desktopqmakerunconfiguration.cpp", "desktopqmakerunconfiguration.h",
"externaleditors.cpp", "externaleditors.h",
"findqmakeprofiles.cpp", "findqmakeprofiles.h",
@@ -37,6 +43,11 @@ QtcPlugin {
"profileeditorfactory.cpp", "profileeditorfactory.h",
"profilehighlighter.cpp", "profilehighlighter.h",
"profilehoverhandler.cpp", "profilehoverhandler.h",
+ "qmakeandroidrunconfiguration.cpp", "qmakeandroidrunconfiguration.h",
+ "qmakeandroidrunfactories.cpp", "qmakeandroidrunfactories.h",
+ "qmakeandroidbuildapkstep.cpp", "qmakeandroidbuildapkstep.h",
+ "qmakeandroidbuildapkwidget.cpp", "qmakeandroidbuildapkwidget.h", "qmakeandroidbuildapkwidget.ui",
+ "qmakeandroidsupport.cpp", "qmakeandroidsupport.h",
"qmakebuildinfo.h",
"qmakekitconfigwidget.cpp", "qmakekitconfigwidget.h",
"qmakekitinformation.cpp", "qmakekitinformation.h",
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager_dependencies.pri b/src/plugins/qmakeprojectmanager/qmakeprojectmanager_dependencies.pri
index 60744c7674..07f17bee56 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager_dependencies.pri
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager_dependencies.pri
@@ -11,6 +11,8 @@ QTC_PLUGIN_DEPENDS += \
texteditor \
cpptools \
qmljstools \
- resourceeditor
+ resourceeditor \
+ android
+
QTC_PLUGIN_RECOMMENDS += \
designer
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp
index 83df8908f6..4633996037 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp
@@ -27,6 +27,11 @@
**
****************************************************************************/
+#include "androidpackageinstallationfactory.h"
+#include "androidqmakebuildconfigurationfactory.h"
+#include "qmakeandroidbuildapkstep.h"
+#include "qmakeandroidrunfactories.h"
+#include "qmakeandroidsupport.h"
#include "qmakeprojectmanagerplugin.h"
#include "qmakeprojectmanager.h"
@@ -133,6 +138,7 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString
addAutoReleasedObject(new MakeStepFactory);
addAutoReleasedObject(new QmakeBuildConfigurationFactory);
+ addAutoReleasedObject(new AndroidQmakeBuildConfigurationFactory);
addAutoReleasedObject(new DesktopQmakeRunConfigurationFactory);
if (Utils::HostOsInfo::isMacHost())
@@ -152,6 +158,12 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString
hf->addMimeType(QmakeProjectManager::Constants::PROFEATUREFILE_MIMETYPE);
addAutoReleasedObject(hf);
+ // Android stuff
+ addAutoReleasedObject(new AndroidPackageInstallationFactory);
+ addAutoReleasedObject(new QmakeAndroidBuildApkStepFactory);
+ addAutoReleasedObject(new QmakeAndroidRunConfigurationFactory);
+ addAutoReleasedObject(new QmakeAndroidSupport);
+
//menus
Core::ActionContainer *mbuild =
Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_BUILDPROJECT);