Android: Make sign package orthogonal to the debug vs release

This enables signing debug packages and creating unsigned release
packages.

Task-number: QTCREATORBUG-10060
Change-Id: I57d094972b451538e8e9e5104e803e50a4ba2336
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Reviewed-by: BogDan Vatra <bogdan@kde.org>
This commit is contained in:
Daniel Teske
2013-08-30 17:28:36 +02:00
parent f869b587de
commit b14a0e58e6
7 changed files with 174 additions and 47 deletions

View File

@@ -39,7 +39,9 @@
#include <coreplugin/messagemanager.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/deployconfiguration.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/target.h>
#include <qt4projectmanager/qt4buildconfiguration.h>
#include <qt4projectmanager/qt4project.h>
@@ -133,8 +135,16 @@ bool AndroidDeployStep::init()
if (!bc)
return false;
m_signPackage = false;
// find AndroidPackageCreationStep
foreach (BuildStep *step, target()->activeDeployConfiguration()->stepList()->steps()) {
if (AndroidPackageCreationStep *apcs = qobject_cast<AndroidPackageCreationStep *>(step)) {
m_signPackage = apcs->signPackage();
break;
}
}
m_qtVersionSourcePath = version->qmakeProperty("QT_INSTALL_PREFIX");
m_qtVersionQMakeBuildConfig = bc->qmakeBuildConfiguration();
m_androidDirPath = AndroidManager::dirPath(target());
m_apkPathDebug = AndroidManager::apkPath(target(), AndroidManager::DebugBuild).toString();
m_apkPathRelease = AndroidManager::apkPath(target(), AndroidManager::ReleaseBuildSigned).toString();
@@ -544,8 +554,7 @@ bool AndroidDeployStep::deployPackage()
AndroidDeviceInfo::adbSelector(m_deviceSerialNumber) << QLatin1String("uninstall") << m_packageName);
QString package = m_apkPathDebug;
if (!(m_qtVersionQMakeBuildConfig & QtSupport::BaseQtVersion::DebugBuild)
&& QFile::exists(m_apkPathRelease))
if (m_signPackage && QFile::exists(m_apkPathRelease))
package = m_apkPathRelease;
if (!runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(),

View File

@@ -146,7 +146,7 @@ private:
QString m_avdName;
QString m_packageName;
QString m_qtVersionSourcePath;
QtSupport::BaseQtVersion::QmakeBuildConfigs m_qtVersionQMakeBuildConfig;
bool m_signPackage;
Utils::FileName m_androidDirPath;
QString m_apkPathDebug;
QString m_apkPathRelease;

View File

@@ -66,6 +66,7 @@ namespace Internal {
namespace {
const QLatin1String KeystoreLocationKey("KeystoreLocation");
const QLatin1String SignPackageKey("SignPackage");
const QLatin1String AliasString("Alias name:");
const QLatin1String CertificateSeparator("*******************************************");
}
@@ -131,6 +132,7 @@ void AndroidPackageCreationStep::ctor()
setDefaultDisplayName(tr("Packaging for Android"));
m_openPackageLocation = true;
m_bundleQt = false;
m_signPackage = false;
connect(&m_outputParser, SIGNAL(addTask(ProjectExplorer::Task)), this, SIGNAL(addTask(ProjectExplorer::Task)));
}
@@ -156,7 +158,6 @@ bool AndroidPackageCreationStep::init()
Utils::FileName androidLibPath = path.appendPath(QLatin1String("libs/") + androidTargetArch);
m_gdbServerDestination = androidLibPath.appendPath(QLatin1String("gdbserver"));
m_gdbServerSource = AndroidGdbServerKitInformation::gdbServer(target()->kit());
m_debugBuild = bc->qmakeBuildConfiguration() & QtSupport::BaseQtVersion::DebugBuild;
if (!AndroidManager::createAndroidTemplatesIfNecessary(target()))
return false;
@@ -165,6 +166,7 @@ bool AndroidPackageCreationStep::init()
m_antToolPath = AndroidConfigurations::instance().antToolPath();
m_apkPathUnsigned = AndroidManager::apkPath(target(), AndroidManager::ReleaseBuildUnsigned);
m_apkPathSigned = AndroidManager::apkPath(target(), AndroidManager::ReleaseBuildSigned);
m_signPackageForRun = m_signPackage;
m_keystorePathForRun = m_keystorePath;
m_certificatePasswdForRun = m_certificatePasswd;
m_jarSigner = AndroidConfigurations::instance().jarsignerPath();
@@ -176,6 +178,10 @@ bool AndroidPackageCreationStep::init()
return false;
initCheckRequiredLibrariesForRun();
if (m_signPackage && (bc->qmakeBuildConfiguration() & QtSupport::BaseQtVersion::DebugBuild))
emit addOutput(tr("Warning: Signing a debug package."), BuildStep::ErrorMessageOutput);
return true;
}
@@ -418,11 +424,22 @@ QAbstractItemModel *AndroidPackageCreationStep::keystoreCertificates()
return new CertificatesModel(rawCerts, this);
}
bool AndroidPackageCreationStep::signPackage() const
{
return m_signPackage;
}
void AndroidPackageCreationStep::setSignPackage(bool b)
{
m_signPackage = b;
}
bool AndroidPackageCreationStep::fromMap(const QVariantMap &map)
{
if (!BuildStep::fromMap(map))
return false;
m_keystorePath = Utils::FileName::fromString(map.value(KeystoreLocationKey).toString());
m_signPackage = map.value(SignPackageKey).toBool();
return true;
}
@@ -430,6 +447,7 @@ QVariantMap AndroidPackageCreationStep::toMap() const
{
QVariantMap map(BuildStep::toMap());
map.insert(KeystoreLocationKey, m_keystorePath.toString());
map.insert(SignPackageKey, m_signPackage);
return map;
}
@@ -637,7 +655,9 @@ bool AndroidPackageCreationStep::createPackage()
QStringList build;
build << QLatin1String("clean");
QFile::remove(m_gdbServerDestination.toString());
if (m_debugBuild || !m_certificateAlias.length()) {
if (m_signPackageForRun) {
build << QLatin1String("release");
} else {
build << QLatin1String("debug");
QDir dir;
dir.mkpath(m_gdbServerDestination.toFileInfo().absolutePath());
@@ -646,8 +666,6 @@ bool AndroidPackageCreationStep::createPackage()
.arg(m_gdbServerDestination.toUserOutput()));
return false;
}
} else {
build << QLatin1String("release");
}
QList<DeployItem> deployFiles;
@@ -711,7 +729,7 @@ bool AndroidPackageCreationStep::createPackage()
return false;
}
if (!(m_debugBuild) && m_certificateAlias.length()) {
if (m_signPackageForRun) {
emit addOutput(tr("Signing package ..."), MessageOutput);
while (true) {
if (m_certificatePasswdForRun.isEmpty())

View File

@@ -72,6 +72,8 @@ public:
void setCertificatePassword(const QString &pwd);
void setOpenPackageLocation(bool open);
QAbstractItemModel *keystoreCertificates();
bool signPackage() const;
void setSignPackage(bool b);
protected:
bool fromMap(const QVariantMap &map);
@@ -115,6 +117,7 @@ private:
private:
void handleProcessOutput(QProcess *process, bool stdErr);
bool m_signPackage;
Utils::FileName m_keystorePath;
QString m_keystorePasswd;
QString m_certificateAlias;
@@ -126,10 +129,10 @@ private:
Utils::FileName m_androidDir;
Utils::FileName m_gdbServerSource;
Utils::FileName m_gdbServerDestination;
bool m_debugBuild;
Utils::FileName m_antToolPath;
Utils::FileName m_apkPathUnsigned;
Utils::FileName m_apkPathSigned;
bool m_signPackageForRun;
Utils::FileName m_keystorePathForRun;
QString m_certificatePasswdForRun;
Utils::FileName m_jarSigner;

View File

@@ -139,12 +139,15 @@ AndroidPackageCreationWidget::AndroidPackageCreationWidget(AndroidPackageCreatio
: ProjectExplorer::BuildStepConfigWidget(),
m_step(step),
m_ui(new Ui::AndroidPackageCreationWidget),
m_fileSystemWatcher(new QFileSystemWatcher(this))
m_fileSystemWatcher(new QFileSystemWatcher(this)),
m_currentBuildConfiguration(0)
{
m_qtLibsModel = new CheckModel(this);
m_prebundledLibs = new CheckModel(this);
m_ui->setupUi(this);
m_ui->signingDebugWarningIcon->hide();
m_ui->signingDebugWarningLabel->hide();
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QTimer::singleShot(50, this, SLOT(initGui()));
connect(m_step, SIGNAL(updateRequiredLibrariesModels()), SLOT(updateRequiredLibrariesModels()));
@@ -184,6 +187,36 @@ void AndroidPackageCreationWidget::initGui()
bool use = bc->useSystemEnvironment();
bc->setUseSystemEnvironment(!use);
bc->setUseSystemEnvironment(use);
activeBuildConfigurationChanged();
connect(m_step->target(), SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
this, SLOT(activeBuildConfigurationChanged()));
}
void AndroidPackageCreationWidget::updateSigningWarning()
{
Qt4BuildConfiguration *bc = qobject_cast<Qt4BuildConfiguration *>(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 AndroidPackageCreationWidget::activeBuildConfigurationChanged()
{
if (m_currentBuildConfiguration)
disconnect(m_currentBuildConfiguration, SIGNAL(qmakeBuildConfigurationChanged()),
this, SLOT(updateSigningWarning()));
updateSigningWarning();
Qt4BuildConfiguration *bc = qobject_cast<Qt4BuildConfiguration *>(m_step->target()->activeBuildConfiguration());
m_currentBuildConfiguration = bc;
if (bc)
connect(bc, SIGNAL(qmakeBuildConfigurationChanged()), this, SLOT(updateSigningWarning()));
m_currentBuildConfiguration = bc;
}
void AndroidPackageCreationWidget::updateAndroidProjectInfo()
@@ -304,6 +337,8 @@ void AndroidPackageCreationWidget::setCertificates()
void AndroidPackageCreationWidget::on_signPackageCheckBox_toggled(bool checked)
{
m_step->setSignPackage(checked);
updateSigningWarning();
if (!checked)
return;
if (!m_step->keystorePath().isEmpty())

View File

@@ -41,6 +41,8 @@ class QFileSystemWatcher;
namespace Ui { class AndroidPackageCreationWidget; }
QT_END_NAMESPACE
namespace Qt4ProjectManager { class Qt4BuildConfiguration; }
namespace Android {
namespace Internal {
class AndroidPackageCreationStep;
@@ -102,12 +104,15 @@ private slots:
void on_openPackageLocationCheckBox_toggled(bool checked);
void updateSigningWarning();
void activeBuildConfigurationChanged();
private:
AndroidPackageCreationStep *const m_step;
Ui::AndroidPackageCreationWidget *const m_ui;
CheckModel *m_qtLibsModel;
CheckModel *m_prebundledLibs;
QFileSystemWatcher *m_fileSystemWatcher;
Qt4ProjectManager::Qt4BuildConfiguration *m_currentBuildConfiguration;
};
} // namespace Internal

View File

@@ -161,9 +161,9 @@
<property name="title">
<string>Sign package</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="KeystoreLocationLabel">
<property name="text">
@@ -197,46 +197,103 @@
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="signPackageCheckBox">
<property name="text">
<string>Sign package</string>
</property>
</widget>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QCheckBox" name="signPackageCheckBox">
<property name="text">
<string>Sign package</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="openPackageLocationCheckBox">
<property name="text">
<string>Open package location after is complete</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="openPackageLocationCheckBox">
<property name="text">
<string>Open package location after is complete</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="KeystoreLocationLabel_2">
<property name="text">
<string>Certificate alias:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="certificatesAliasComboBox">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
<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="../projectexplorer/projectexplorer.qrc">:/projectexplorer/images/compile_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>
</layout>
</widget>
<resources/>
<resources>
<include location="../projectexplorer/projectexplorer.qrc"/>
</resources>
<connections>
<connection>
<sender>signPackageCheckBox</sender>