Commit 12623107 authored by Daniel Teske's avatar Daniel Teske

Android: androiddeployqt support

Change-Id: I37d706b4e11c6e1353a8ee73378b7d080080678c
Reviewed-by: default avatarEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
parent 455d597a
......@@ -42,7 +42,10 @@ HEADERS += \
androidmanifesteditor.h \
androidmanifesteditorwidget.h \
androidmanifestdocument.h \
androiddevicedialog.h
androiddevicedialog.h \
androiddeployqtstep.h \
certificatesmodel.h \
androiddeployqtwidget.h
SOURCES += \
androidconfigurations.cpp \
......@@ -79,7 +82,10 @@ SOURCES += \
androidmanifesteditor.cpp \
androidmanifesteditorwidget.cpp \
androidmanifestdocument.cpp \
androiddevicedialog.cpp
androiddevicedialog.cpp \
androiddeployqtstep.cpp \
certificatesmodel.cpp \
androiddeployqtwidget.cpp
FORMS += \
androidsettingswidget.ui \
......@@ -87,7 +93,8 @@ FORMS += \
androiddeploystepwidget.ui \
addnewavddialog.ui \
androidcreatekeystorecertificate.ui \
androiddevicedialog.ui
androiddevicedialog.ui \
androiddeployqtwidget.ui
exists(../../shared/qbs/qbs.pro) {
HEADERS += \
......
......@@ -36,6 +36,8 @@ QtcPlugin {
"androidcreatekeystorecertificate.cpp",
"androidcreatekeystorecertificate.h",
"androidcreatekeystorecertificate.ui",
"androiddeployqtstep.cpp",
"androiddeployqtstep.h",
"androiddebugsupport.cpp",
"androiddebugsupport.h",
"androiddevicedialog.cpp",
......@@ -50,6 +52,9 @@ QtcPlugin {
"androiddeploystepwidget.cpp",
"androiddeploystepwidget.h",
"androiddeploystepwidget.ui",
"androiddeployqtwidget.cpp",
"androiddeployqtwidget.h",
"androiddeployqtwidget.ui",
"androiddevice.cpp",
"androiddevice.h",
"androiddevicefactory.cpp",
......@@ -103,6 +108,8 @@ QtcPlugin {
"androidsettingswidget.ui",
"androidtoolchain.cpp",
"androidtoolchain.h",
"certificatesmodel.cpp",
"certificatesmodel.h",
"javaparser.cpp",
"javaparser.h",
]
......
......@@ -715,6 +715,13 @@ QStringList AndroidConfigurations::getAbis(const QString &device) const
return result;
}
QString AndroidConfigurations::highestAvailableAndroidPlatform() const
{
if (m_availablePlatforms.isEmpty())
return QString();
return QLatin1String("android-") + QString::number(m_availablePlatforms.first());
}
QString AndroidConfigurations::bestMatch(const QString &targetAPI) const
{
int target = targetAPI.mid(targetAPI.lastIndexOf(QLatin1Char('-')) + 1).toInt();
......
......@@ -124,6 +124,7 @@ public:
AndroidDeviceInfo showDeviceDialog(ProjectExplorer::Project *project, int apiLevel, const QString &abi);
void setDefaultDevice(ProjectExplorer::Project *project, const QString &abi, const QString &serialNumber); // serial number or avd name
QString defaultDevice(ProjectExplorer::Project *project, const QString &abi) const; // serial number or avd name
QString highestAvailableAndroidPlatform() const;
public slots:
void clearDefaultDevices(ProjectExplorer::Project *project);
......
......@@ -32,6 +32,7 @@
#include "androiddeploystep.h"
#include "androidpackageinstallationstep.h"
#include "androidpackagecreationstep.h"
#include "androiddeployqtstep.h"
#include "androidmanager.h"
#include <projectexplorer/buildsteplist.h>
......@@ -76,9 +77,15 @@ DeployConfiguration *AndroidDeployConfigurationFactory::create(Target *parent, c
AndroidDeployConfiguration *dc = new AndroidDeployConfiguration(parent, id);
if (!dc)
return 0;
dc->stepList()->insertStep(0, new AndroidPackageInstallationStep(dc->stepList()));
dc->stepList()->insertStep(1, new AndroidPackageCreationStep(dc->stepList()));
dc->stepList()->insertStep(2, new AndroidDeployStep(dc->stepList()));
if (id == ANDROID_DEPLOYCONFIGURATION_ID) {
dc->stepList()->insertStep(0, new AndroidPackageInstallationStep(AndroidPackageInstallationStep::ProjectDirectory, dc->stepList()));
dc->stepList()->insertStep(1, new AndroidPackageCreationStep(dc->stepList()));
dc->stepList()->insertStep(2, new AndroidDeployStep(dc->stepList()));
} else {
dc->stepList()->insertStep(0, new AndroidPackageInstallationStep(AndroidPackageInstallationStep::BuildDirectory, dc->stepList()));
dc->stepList()->insertStep(1, new AndroidDeployQtStep(dc->stepList()));
}
return dc;
}
......@@ -104,7 +111,7 @@ bool AndroidDeployConfigurationFactory::canClone(Target *parent, DeployConfigura
{
if (!AndroidManager::supportsAndroid(parent))
return false;
return source->id() == ANDROID_DEPLOYCONFIGURATION_ID;
return canCreate(parent, source->id());
}
DeployConfiguration *AndroidDeployConfigurationFactory::clone(Target *parent, DeployConfiguration *source)
......@@ -128,16 +135,20 @@ QList<Core::Id> AndroidDeployConfigurationFactory::availableCreationIds(Target *
if (!tc || tc->targetAbi().osFlavor() != Abi::AndroidLinuxFlavor)
return ids;
if (QtSupport::QtKitInformation::qtVersion(parent->kit())->type() != QLatin1String(Constants::ANDROIDQT))
QtSupport::BaseQtVersion *qt = QtSupport::QtKitInformation::qtVersion(parent->kit());
if (qt->type() != QLatin1String(Constants::ANDROIDQT))
return ids;
ids << Core::Id(ANDROID_DEPLOYCONFIGURATION_ID);
if (qt->qtVersion() < QtSupport::QtVersionNumber(5, 2, 0))
ids << Core::Id(ANDROID_DEPLOYCONFIGURATION_ID);
else
ids << Core::Id(ANDROID_DEPLOYCONFIGURATION2_ID);
return ids;
}
QString AndroidDeployConfigurationFactory::displayNameForId(const Core::Id id) const
{
if (id.name().startsWith(ANDROID_DC_PREFIX))
if (id.name().startsWith(ANDROID_DC_PREFIX)
|| id.name().startsWith(ANDROID_DC2_PREFIX))
return tr("Deploy on Android");
return QString();
}
......
......@@ -38,6 +38,10 @@ namespace Internal {
const char ANDROID_DEPLOYCONFIGURATION_ID[] = "Qt4ProjectManager.AndroidDeployConfiguration";
const char ANDROID_DC_PREFIX[] = "Qt4ProjectManager.AndroidDeployConfiguration.";
// Qt 5.2 has a new form of deployment
const char ANDROID_DEPLOYCONFIGURATION2_ID[] = "Qt4ProjectManager.AndroidDeployConfiguration2";
const char ANDROID_DC2_PREFIX[] = "Qt4ProjectManager.AndroidDeployConfiguration2.";
class AndroidDeployConfiguration : public ProjectExplorer::DeployConfiguration
{
Q_OBJECT
......
This diff is collapsed.
/**************************************************************************
**
** Copyright (c) 2013 BogDan Vatra <bog_dan_ro@yahoo.com>
** Copyright (C) 2013 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 ANDROIDDEPLOYQTSTEP_H
#define ANDROIDDEPLOYQTSTEP_H
#include "androidconfigurations.h"
#include <projectexplorer/abstractprocessstep.h>
#include <qtsupport/baseqtversion.h>
QT_BEGIN_NAMESPACE
class QAbstractItemModel;
QT_END_NAMESPACE
namespace Android {
namespace Internal {
class AndroidDeployQtStepFactory : public ProjectExplorer::IBuildStepFactory
{
Q_OBJECT
public:
explicit AndroidDeployQtStepFactory(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);
};
class AndroidDeployQtStep : public ProjectExplorer::AbstractProcessStep
{
Q_OBJECT
friend class AndroidDeployQtStepFactory;
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 inputFile() const;
void setInputFile(const QString &file);
signals:
// also on purpose emitted if the possible values of this changed
void inputFileChanged();
public slots:
void setDeployAction(AndroidDeployQtAction deploy); // slot?
private slots:
void showInGraphicalShell();
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);
QString m_buildTargetSdk;
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_inputFile;
int m_deviceAPILevel;
static const Core::Id Id;
};
}
}
#endif // ANDROIDDEPLOYQTSTEP_H
This diff is collapsed.
/**************************************************************************
**
** Copyright (c) 2013 BogDan Vatra <bog_dan_ro@yahoo.com>
** Copyright (C) 2013 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 ANDROIDDEPLOYQTWIDGET_H
#define ANDROIDDEPLOYQTWIDGET_H
#include <projectexplorer/buildstep.h>
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class AndroidDeployQtWidget; }
QT_END_NAMESPACE
namespace Qt4ProjectManager { class Qt4BuildConfiguration; }
namespace Android {
namespace Internal {
class AndroidDeployQtStep;
class AndroidDeployQtWidget : public ProjectExplorer::BuildStepConfigWidget
{
Q_OBJECT
public:
AndroidDeployQtWidget(AndroidDeployQtStep *step);
~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 browseKeyStore();
void signPackageCheckBoxToggled(bool checked);
void updateInputFileUi();
void inputFileComboBoxIndexChanged();
private:
virtual QString summaryText() const;
virtual QString displayName() const;
void setCertificates();
Ui::AndroidDeployQtWidget *m_ui;
AndroidDeployQtStep *m_step;
Qt4ProjectManager::Qt4BuildConfiguration *m_currentBuildConfiguration;
bool m_ignoreChange;
};
}
}
#endif // ANDROIDDEPLOYQTWIDGET_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AndroidDeployQtWidget</class>
<widget class="QWidget" name="AndroidDeployQtWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>682</width>
<height>415</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="QLineEdit" name="KeystoreLocationLineEdit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="KeystoreCreatePushButton">
<property name="text">
<string>Create</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="KeystoreLocationPushButton">
<property name="text">
<string>Browse</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="../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>
<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>Use 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="temporaryQtOption">
<property name="toolTip">
<string>Push 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>
<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>
</layout>
</widget>
</item>
<item row="3" column="1">
<widget class="QGroupBox" name="advancedActions">
<property name="title">
<string>Advanced Actions</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="0">
<widget class="QPushButton" name="cleanLibsPushButton">
<property name="text">
<string>Clean Temporary Libraries Directory on Device</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QPushButton" name="installMinistroButton">
<property name="text">
<string>Install Ministro from APK</string>
</property>
</widget>
</item>
<item row="2" column="0">
<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 is complete</string>
</property>
</widget>
</item>
<item row="1" column="0">