diff options
author | Tobias Hunger <[email protected]> | 2012-04-24 15:49:09 +0200 |
---|---|---|
committer | Tobias Hunger <[email protected]> | 2012-06-21 12:08:12 +0200 |
commit | 24314562165588b56a318b3b8a846bf5deda7c41 (patch) | |
tree | b5dcf951e76d003c2623011b0e91994e06e7e061 /src/plugins/android | |
parent | 8c77b8c9d7b25d0c89003c8c4a54e8da5bfb7edd (diff) |
Profile introduction
Introduce Profiles to store sets of values that describe a system/device.
These profiles are held by a target, getting rid of much of the information
stored in the Build-/Run-/DeployConfigurations, greatly simplifying those.
This is a squash of the wip/profile branch which has been on gerrit for a
while, rebased to current master.
Change-Id: I25956c8dd4d1962b2134bfaa8a8076ae3909460f
Reviewed-by: Daniel Teske <[email protected]>
Diffstat (limited to 'src/plugins/android')
39 files changed, 1280 insertions, 1659 deletions
diff --git a/src/plugins/android/android.pro b/src/plugins/android/android.pro index c841fdbae01..2ebfd680bd5 100644 --- a/src/plugins/android/android.pro +++ b/src/plugins/android/android.pro @@ -12,6 +12,7 @@ QT += xml network HEADERS += \ androidconstants.h \ androidconfigurations.h \ + androidmanager.h \ androidrunconfiguration.h \ androidruncontrol.h \ androidrunfactories.h \ @@ -32,14 +33,13 @@ HEADERS += \ androidqtversionfactory.h \ androidqtversion.h \ androiddeployconfiguration.h \ - androidtarget.h \ - androidtargetfactory.h \ androidcreatekeystorecertificate.h \ javaparser.h \ androidplugin.h SOURCES += \ androidconfigurations.cpp \ + androidmanager.cpp \ androidrunconfiguration.cpp \ androidruncontrol.cpp \ androidrunfactories.cpp \ @@ -59,8 +59,6 @@ SOURCES += \ androidqtversionfactory.cpp \ androidqtversion.cpp \ androiddeployconfiguration.cpp \ - androidtarget.cpp \ - androidtargetfactory.cpp \ androidcreatekeystorecertificate.cpp \ javaparser.cpp \ androidplugin.cpp diff --git a/src/plugins/android/android.qbs b/src/plugins/android/android.qbs index f4b43ad7197..397648e7920 100644 --- a/src/plugins/android/android.qbs +++ b/src/plugins/android/android.qbs @@ -42,6 +42,8 @@ QtcPlugin { "androiddeploystepwidget.h", "androiddeploystepwidget.ui", "androidglobal.h", + "androidmanager.h", + "androidmanager.cpp", "androidpackagecreationfactory.cpp", "androidpackagecreationfactory.h", "androidpackagecreationstep.cpp", @@ -73,10 +75,6 @@ QtcPlugin { "androidsettingswidget.cpp", "androidsettingswidget.h", "androidsettingswidget.ui", - "androidtarget.cpp", - "androidtargetfactory.cpp", - "androidtargetfactory.h", - "androidtarget.h", "androidtoolchain.cpp", "androidtoolchain.h", "javaparser.cpp", diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index 88ee1144bf9..18737287351 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -124,16 +124,16 @@ QLatin1String AndroidConfigurations::toolsPrefix(ProjectExplorer::Abi::Architect AndroidConfig::AndroidConfig(const QSettings &settings) { // user settings - armGdbLocation = settings.value(ArmGdbLocationKey).toString(); - armGdbserverLocation = settings.value(ArmGdbserverLocationKey).toString(); - x86GdbLocation = settings.value(X86GdbLocationKey).toString(); - x86GdbserverLocation = settings.value(X86GdbserverLocationKey).toString(); + armGdbLocation = Utils::FileName::fromString(settings.value(ArmGdbLocationKey).toString()); + armGdbserverLocation = Utils::FileName::fromString(settings.value(ArmGdbserverLocationKey).toString()); + x86GdbLocation = Utils::FileName::fromString(settings.value(X86GdbLocationKey).toString()); + x86GdbserverLocation = Utils::FileName::fromString(settings.value(X86GdbserverLocationKey).toString()); partitionSize = settings.value(PartitionSizeKey, 1024).toInt(); - sdkLocation = settings.value(SDKLocationKey).toString(); - ndkLocation = settings.value(NDKLocationKey).toString(); - antLocation = settings.value(AntLocationKey).toString(); - openJDKLocation = settings.value(OpenJDKLocationKey).toString(); - keystoreLocation = settings.value(KeystoreLocationKey).toString(); + sdkLocation = Utils::FileName::fromString(settings.value(SDKLocationKey).toString()); + ndkLocation = Utils::FileName::fromString(settings.value(NDKLocationKey).toString()); + antLocation = Utils::FileName::fromString(settings.value(AntLocationKey).toString()); + openJDKLocation = Utils::FileName::fromString(settings.value(OpenJDKLocationKey).toString()); + keystoreLocation = Utils::FileName::fromString(settings.value(KeystoreLocationKey).toString()); QRegExp versionRegExp(NDKGccVersionRegExp); const QString &value = settings.value(NDKToolchainVersionKey).toString(); @@ -147,11 +147,11 @@ AndroidConfig::AndroidConfig(const QSettings &settings) if (reader.load(settingsFileName()) && settings.value(changeTimeStamp).toInt() != QFileInfo(settingsFileName()).lastModified().toMSecsSinceEpoch() / 1000) { // persisten settings - sdkLocation = reader.restoreValue(SDKLocationKey).toString(); - ndkLocation = reader.restoreValue(NDKLocationKey).toString(); - antLocation = reader.restoreValue(AntLocationKey).toString(); - openJDKLocation = reader.restoreValue(OpenJDKLocationKey).toString(); - keystoreLocation = reader.restoreValue(KeystoreLocationKey).toString(); + sdkLocation = Utils::FileName::fromString(reader.restoreValue(SDKLocationKey).toString()); + ndkLocation = Utils::FileName::fromString(reader.restoreValue(NDKLocationKey).toString()); + antLocation = Utils::FileName::fromString(reader.restoreValue(AntLocationKey).toString()); + openJDKLocation = Utils::FileName::fromString(reader.restoreValue(OpenJDKLocationKey).toString()); + keystoreLocation = Utils::FileName::fromString(reader.restoreValue(KeystoreLocationKey).toString()); QRegExp versionRegExp(NDKGccVersionRegExp); const QString &value = reader.restoreValue(NDKToolchainVersionKey).toString(); @@ -160,17 +160,17 @@ AndroidConfig::AndroidConfig(const QSettings &settings) else ndkToolchainVersion = value.mid(versionRegExp.indexIn(value)); - if (!armGdbLocation.length()) - armGdbLocation = reader.restoreValue(ArmGdbLocationKey).toString(); + if (armGdbLocation.isEmpty()) + armGdbLocation = Utils::FileName::fromString(reader.restoreValue(ArmGdbLocationKey).toString()); - if (!armGdbserverLocation.length()) - armGdbserverLocation = reader.restoreValue(ArmGdbserverLocationKey).toString(); + if (armGdbserverLocation.isEmpty()) + armGdbserverLocation = Utils::FileName::fromString(reader.restoreValue(ArmGdbserverLocationKey).toString()); - if (!x86GdbLocation.length()) - x86GdbLocation = reader.restoreValue(X86GdbLocationKey).toString(); + if (x86GdbLocation.isEmpty()) + x86GdbLocation = Utils::FileName::fromString(reader.restoreValue(X86GdbLocationKey).toString()); - if (!x86GdbserverLocation.length()) - x86GdbserverLocation = reader.restoreValue(X86GdbserverLocationKey).toString(); + if (x86GdbserverLocation.isEmpty()) + x86GdbserverLocation = Utils::FileName::fromString(reader.restoreValue(X86GdbserverLocationKey).toString()); // persistent settings } @@ -188,16 +188,16 @@ void AndroidConfig::save(QSettings &settings) const settings.setValue(changeTimeStamp, fileInfo.lastModified().toMSecsSinceEpoch() / 1000); // user settings - settings.setValue(SDKLocationKey, sdkLocation); - settings.setValue(NDKLocationKey, ndkLocation); + settings.setValue(SDKLocationKey, sdkLocation.toString()); + settings.setValue(NDKLocationKey, ndkLocation.toString()); settings.setValue(NDKToolchainVersionKey, ndkToolchainVersion); - settings.setValue(AntLocationKey, antLocation); - settings.setValue(OpenJDKLocationKey, openJDKLocation); - settings.setValue(KeystoreLocationKey, keystoreLocation); - settings.setValue(ArmGdbLocationKey, armGdbLocation); - settings.setValue(ArmGdbserverLocationKey, armGdbserverLocation); - settings.setValue(X86GdbLocationKey, x86GdbLocation); - settings.setValue(X86GdbserverLocationKey, x86GdbserverLocation); + settings.setValue(AntLocationKey, antLocation.toString()); + settings.setValue(OpenJDKLocationKey, openJDKLocation.toString()); + settings.setValue(KeystoreLocationKey, keystoreLocation.toString()); + settings.setValue(ArmGdbLocationKey, armGdbLocation.toString()); + settings.setValue(ArmGdbserverLocationKey, armGdbserverLocation.toString()); + settings.setValue(X86GdbLocationKey, x86GdbLocation.toString()); + settings.setValue(X86GdbserverLocationKey, x86GdbserverLocation.toString()); settings.setValue(PartitionSizeKey, partitionSize); // user settings @@ -214,7 +214,7 @@ void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs) void AndroidConfigurations::updateAvailablePlatforms() { m_availablePlatforms.clear(); - QDirIterator it(m_config.ndkLocation + QLatin1String("/platforms"), QStringList() << QLatin1String("android-*"), QDir::Dirs); + QDirIterator it(m_config.ndkLocation.appendPath(QLatin1String("platforms")).toString(), QStringList() << QLatin1String("android-*"), QDir::Dirs); while (it.hasNext()) { const QString &fileName = it.next(); m_availablePlatforms.push_back(fileName.mid(fileName.lastIndexOf(QLatin1Char('-')) + 1).toInt()); @@ -226,7 +226,7 @@ QStringList AndroidConfigurations::sdkTargets(int minApiLevel) const { QStringList targets; QProcess proc; - proc.start(androidToolPath(), QStringList() << QLatin1String("list") << QLatin1String("target")); // list avaialbe AVDs + proc.start(androidToolPath().toString(), QStringList() << QLatin1String("list") << QLatin1String("target")); // list avaialbe AVDs if (!proc.waitForFinished(-1)) { proc.terminate(); return targets; @@ -248,7 +248,8 @@ QStringList AndroidConfigurations::ndkToolchainVersions() const { QRegExp versionRegExp(NDKGccVersionRegExp); QStringList result; - QDirIterator it(m_config.ndkLocation + QLatin1String("/toolchains"), + Utils::FileName path = m_config.ndkLocation; + QDirIterator it(path.appendPath(QLatin1String("toolchains")).toString(), QStringList() << QLatin1String("*"), QDir::Dirs); while (it.hasNext()) { const QString &fileName = it.next(); @@ -262,66 +263,71 @@ QStringList AndroidConfigurations::ndkToolchainVersions() const return result; } -QString AndroidConfigurations::adbToolPath() const +Utils::FileName AndroidConfigurations::adbToolPath() const { - return m_config.sdkLocation + QLatin1String("/platform-tools/adb" ANDROID_EXE_SUFFIX); + Utils::FileName path = m_config.sdkLocation; + return path.appendPath(QLatin1String("platform-tools/adb"ANDROID_EXE_SUFFIX)); } -QString AndroidConfigurations::androidToolPath() const +Utils::FileName AndroidConfigurations::androidToolPath() const { #ifdef Q_OS_WIN32 // I want to switch from using android.bat to using an executable. All it really does is call // Java and I've made some progress on it. So if android.exe exists, return that instead. - QFileInfo fi(m_config.sdkLocation + QLatin1String("/tools/android" ANDROID_EXE_SUFFIX)); - if (fi.exists()) - return m_config.sdkLocation + QString("/tools/android" ANDROID_EXE_SUFFIX); - else - return m_config.sdkLocation + QLatin1String("/tools/android" ANDROID_BAT_SUFFIX); + Utils::FileName path = m_config.sdkLocation; + path.appendPath(QLatin1String("tools/android"ANDROID_EXE_SUFFIX)); + if (path.toFileInfo().exists()) + return path; + path = m_config.sdkLocation; + return path.appendPath(QLatin1String("tools/android"ANDROID_BAT_SUFFIX)); #else - return m_config.sdkLocation + QLatin1String("/tools/android" ANDROID_EXE_SUFFIX); + Utils::FileName path = m_config.sdkLocation; + return path.appendPath(QLatin1String("tools/android"ANDROID_EXE_SUFFIX)); #endif } -QString AndroidConfigurations::antToolPath() const +Utils::FileName AndroidConfigurations::antToolPath() const { - if (m_config.antLocation.length()) + if (!m_config.antLocation.isEmpty()) return m_config.antLocation; else - return QLatin1String("ant"); + return Utils::FileName::fromString(QLatin1String("ant")); } -QString AndroidConfigurations::emulatorToolPath() const +Utils::FileName AndroidConfigurations::emulatorToolPath() const { - return m_config.sdkLocation + QLatin1String("/tools/emulator" ANDROID_EXE_SUFFIX); + Utils::FileName path = m_config.sdkLocation; + return path.appendPath(QLatin1String("tools/emulator"ANDROID_EXE_SUFFIX)); } -QString AndroidConfigurations::toolPath(ProjectExplorer::Abi::Architecture architecture) const +Utils::FileName AndroidConfigurations::toolPath(ProjectExplorer::Abi::Architecture architecture) const { - return m_config.ndkLocation + QString::fromLatin1("/toolchains/%1-%2/prebuilt/%3/bin/%4") + Utils::FileName path = m_config.ndkLocation; + return path.appendPath(QString::fromLatin1("toolchains/%1-%2/prebuilt/%3/bin/%4") .arg(toolchainPrefix(architecture)) .arg(m_config.ndkToolchainVersion) .arg(ToolchainHost) - .arg(toolsPrefix(architecture)); + .arg(toolsPrefix(architecture))); } -QString AndroidConfigurations::stripPath(ProjectExplorer::Abi::Architecture architecture) const +Utils::FileName AndroidConfigurations::stripPath(ProjectExplorer::Abi::Architecture architecture) const { - return toolPath(architecture) + QLatin1String("-strip" ANDROID_EXE_SUFFIX); + return toolPath(architecture).append(QLatin1String("-strip"ANDROID_EXE_SUFFIX)); } -QString AndroidConfigurations::readelfPath(ProjectExplorer::Abi::Architecture architecture) const +Utils::FileName AndroidConfigurations::readelfPath(ProjectExplorer::Abi::Architecture architecture) const { - return toolPath(architecture) + QLatin1String("-readelf" ANDROID_EXE_SUFFIX); + return toolPath(architecture).append(QLatin1String("-readelf"ANDROID_EXE_SUFFIX)); } -QString AndroidConfigurations::gccPath(ProjectExplorer::Abi::Architecture architecture) const +Utils::FileName AndroidConfigurations::gccPath(ProjectExplorer::Abi::Architecture architecture) const { - return toolPath(architecture) + QLatin1String("-gcc" ANDROID_EXE_SUFFIX); + return toolPath(architecture).append(QLatin1String("-gcc"ANDROID_EXE_SUFFIX)); } -QString AndroidConfigurations::gdbServerPath(ProjectExplorer::Abi::Architecture architecture) const +Utils::FileName AndroidConfigurations::gdbServerPath(ProjectExplorer::Abi::Architecture architecture) const { - QString gdbServerPath; + Utils::FileName gdbServerPath; switch (architecture) { case ProjectExplorer::Abi::ArmArchitecture: gdbServerPath = m_config.armGdbserverLocation; @@ -330,20 +336,21 @@ QString AndroidConfigurations::gdbServerPath(ProjectExplorer::Abi::Architecture gdbServerPath = m_config.x86GdbserverLocation; break; default: - gdbServerPath = Unknown; + gdbServerPath = Utils::FileName::fromString(Unknown); break; } - if (gdbServerPath.length()) + if (!gdbServerPath.isEmpty()) return gdbServerPath; - return m_config.ndkLocation + QString::fromLatin1("/toolchains/%1-%2/prebuilt/gdbserver") - .arg(toolchainPrefix(architecture)) - .arg(m_config.ndkToolchainVersion); + Utils::FileName path = m_config.ndkLocation; + return path.appendPath(QString::fromLatin1("toolchains/%1-%2/prebuilt/gdbserver") + .arg(toolchainPrefix(architecture)) + .arg(m_config.ndkToolchainVersion)); } -QString AndroidConfigurations::gdbPath(ProjectExplorer::Abi::Architecture architecture) const +Utils::FileName AndroidConfigurations::gdbPath(ProjectExplorer::Abi::Architecture architecture) const { - QString gdbPath; + Utils::FileName gdbPath; switch (architecture) { case ProjectExplorer::Abi::ArmArchitecture: gdbPath = m_config.armGdbLocation; @@ -352,45 +359,47 @@ QString AndroidConfigurations::gdbPath(ProjectExplorer::Abi::Architecture archit gdbPath = m_config.x86GdbLocation; break; default: - gdbPath = Unknown; + gdbPath = Utils::FileName::fromString(Unknown); break; } if (!gdbPath.isEmpty()) return gdbPath; - return toolPath(architecture) + QLatin1String("-gdb" ANDROID_EXE_SUFFIX); + return toolPath(architecture).append(QLatin1String("-gdb"ANDROID_EXE_SUFFIX)); } -QString AndroidConfigurations::openJDKPath() const +Utils::FileName AndroidConfigurations::openJDKPath() const { return m_config.openJDKLocation; } -QString AndroidConfigurations::openJDKBinPath() const +Utils::FileName AndroidConfigurations::openJDKBinPath() const { - if (m_config.openJDKLocation.length()) - return m_config.openJDKLocation + QLatin1String("/bin/"); - return QString(); + Utils::FileName path = m_config.openJDKLocation; + if (!path.isEmpty()) + return path.appendPath(QLatin1String("bin")); + return path; } -QString AndroidConfigurations::keytoolPath() const +Utils::FileName AndroidConfigurations::keytoolPath() const { - return openJDKBinPath() + keytoolName; + return openJDKBinPath().appendPath(keytoolName); } -QString AndroidConfigurations::jarsignerPath() const +Utils::FileName AndroidConfigurations::jarsignerPath() const { - return openJDKBinPath() + jarsignerName; + return openJDKBinPath().appendPath(jarsignerName); } QString AndroidConfigurations::getDeployDeviceSerialNumber(int *apiLevel) const { QVector<AndroidDevice> devices = connectedDevices(); - foreach (AndroidDevice device, devices) + foreach (AndroidDevice device, devices) { if (device.sdk >= *apiLevel) { *apiLevel = device.sdk; return device.serialNumber; } + } return startAVD(apiLevel); } @@ -398,7 +407,7 @@ QVector<AndroidDevice> AndroidConfigurations::connectedDevices(int apiLevel) con { QVector<AndroidDevice> devices; QProcess adbProc; - adbProc.start(adbToolPath(), QStringList() << QLatin1String("devices")); + adbProc.start(adbToolPath().toString(), QStringList() << QLatin1String("devices")); if (!adbProc.waitForFinished(-1)) { adbProc.terminate(); return devices; @@ -443,7 +452,7 @@ bool AndroidConfigurations::createAVD(int minApiLevel) const bool AndroidConfigurations::createAVD(const QString &target, const QString &name, int sdcardSize ) const { QProcess proc; - proc.start(androidToolPath(), + proc.start(androidToolPath().toString(), QStringList() << QLatin1String("create") << QLatin1String("avd") << QLatin1String("-a") << QLatin1String("-t") << target << QLatin1String("-n") << name @@ -461,7 +470,7 @@ bool AndroidConfigurations::createAVD(const QString &target, const QString &name bool AndroidConfigurations::removeAVD(const QString &name) const { QProcess proc; - proc.start(androidToolPath(), + proc.start(androidToolPath().toString(), QStringList() << QLatin1String("delete") << QLatin1String("avd") << QLatin1String("-n") << name); if (!proc.waitForFinished(-1)) { @@ -475,7 +484,7 @@ QVector<AndroidDevice> AndroidConfigurations::androidVirtualDevices() const { QVector<AndroidDevice> devices; QProcess proc; - proc.start(androidToolPath(), + proc.start(androidToolPath().toString(), QStringList() << QLatin1String("list") << QLatin1String("avd")); // list available AVDs if (!proc.waitForFinished(-1)) { proc.terminate(); @@ -540,7 +549,7 @@ QString AndroidConfigurations::startAVD(int *apiLevel, const QString &name) cons return avdName; // start the emulator - m_avdProcess->start(emulatorToolPath(), + m_avdProcess->start(emulatorToolPath().toString(), QStringList() << QLatin1String("-partition-size") << QString::number(config().partitionSize) << QLatin1String("-avd") << avdName); if (!m_avdProcess->waitForStarted(-1)) { @@ -550,7 +559,7 @@ QString AndroidConfigurations::startAVD(int *apiLevel, const QString &name) cons // wait until the emulator is online QProcess proc; - proc.start(adbToolPath(), QStringList() << QLatin1String("-e") << QLatin1String("wait-for-device")); + proc.start(adbToolPath().toString(), QStringList() << QLatin1String("-e") << QLatin1String("wait-for-device")); if (!proc.waitForFinished(-1)) { proc.terminate(); return QString(); @@ -558,7 +567,7 @@ QString AndroidConfigurations::startAVD(int *apiLevel, const QString &name) cons sleep(5);// wait for pm to start // workaround for stupid adb bug - proc.start(adbToolPath(), QStringList() << QLatin1String("devices")); + proc.start(adbToolPath().toString(), QStringList() << QLatin1String("devices")); if (!proc.waitForFinished(-1)) { proc.terminate(); return QString(); @@ -577,7 +586,7 @@ int AndroidConfigurations::getSDKVersion(const QString &device) const { QProcess adbProc; - adbProc.start(adbToolPath(), + adbProc.start(adbToolPath().toString(), QStringList() << QLatin1String("-s") << device << QLatin1String("shell") << QLatin1String("getprop") << QLatin1String("ro.build.version.sdk")); diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h index 6fc01f0796a..31eedb4573e 100644 --- a/src/plugins/android/androidconfigurations.h +++ b/src/plugins/android/androidconfigurations.h @@ -67,16 +67,16 @@ public: AndroidConfig(const QSettings &settings); void save(QSettings &settings) const; - QString sdkLocation; - QString ndkLocation; + Utils::FileName sdkLocation; + Utils::FileName ndkLocation; QString ndkToolchainVersion; - QString antLocation; - QString armGdbLocation; - QString armGdbserverLocation; - QString x86GdbLocation; - QString x86GdbserverLocation; - QString openJDKLocation; - QString keystoreLocation; + Utils::FileName antLocation; + Utils::FileName armGdbLocation; + Utils::FileName armGdbserverLocation; + Utils::FileName x86GdbLocation; + Utils::FileName x86GdbserverLocation; + Utils::FileName openJDKLocation; + Utils::FileName keystoreLocation; unsigned partitionSize; }; @@ -97,18 +97,18 @@ public: void setConfig(const AndroidConfig &config); QStringList sdkTargets(int minApiLevel = 0) const; QStringList ndkToolchainVersions() const; - QString adbToolPath() const; - QString androidToolPath() const; - QString antToolPath() const; - QString emulatorToolPath() const; - QString gccPath(ProjectExplorer::Abi::Architecture architecture) const; - QString gdbServerPath(ProjectExplorer::Abi::Architecture architecture) const; - QString gdbPath(ProjectExplorer::Abi::Architecture architecture) const; - QString openJDKPath() const; - QString keytoolPath() const; - QString jarsignerPath() const; - QString stripPath(ProjectExplorer::Abi::Architecture architecture) const; - QString readelfPath(ProjectExplorer::Abi::Architecture architecture) const; + Utils::FileName adbToolPath() const; + Utils::FileName androidToolPath() const; + Utils::FileName antToolPath() const; + Utils::FileName emulatorToolPath() const; + Utils::FileName gccPath(ProjectExplorer::Abi::Architecture architecture) const; + Utils::FileName gdbServerPath(ProjectExplorer::Abi::Architecture architecture) const; + Utils::FileName gdbPath(ProjectExplorer::Abi::Architecture architecture) const; + Utils::FileName openJDKPath() const; + Utils::FileName keytoolPath() const; + Utils::FileName jarsignerPath() const; + Utils::FileName stripPath(ProjectExplorer::Abi::Architecture architecture) const; + Utils::FileName readelfPath(ProjectExplorer::Abi::Architecture architecture) const; QString getDeployDeviceSerialNumber(int *apiLevel) const; bool createAVD(const QString &target, const QString &name, int sdcardSize) const; bool removeAVD(const QString &name) const; @@ -127,8 +127,8 @@ public slots: bool createAVD(int minApiLevel = 0) const; private: - QString toolPath(ProjectExplorer::Abi::Architecture architecture) const; - QString openJDKBinPath() const; + Utils::FileName toolPath(ProjectExplorer::Abi::Architecture architecture) const; + Utils::FileName openJDKBinPath() const; AndroidConfigurations(QObject *parent); void load(); diff --git a/src/plugins/android/androidconstants.h b/src/plugins/android/androidconstants.h index c7a0b9ae891..ab31c92b088 100644 --- a/src/plugins/android/androidconstants.h +++ b/src/plugins/android/androidconstants.h @@ -56,18 +56,8 @@ enum AndroidQemuStatus { #define ANDROID_BAT_SUFFIX "" #endif -static const char ANDROID_RC_ID[] = ANDROID_PREFIX; static const QLatin1String ANDROID_RC_ID_PREFIX(ANDROID_PREFIX "."); -static const QLatin1String AndroidArgumentsKey(ANDROID_PREFIX ".Arguments"); -static const QLatin1String AndroidSimulatorPathKey(ANDROID_PREFIX ".Simulator"); -static const QLatin1String AndroidDeviceIdKey(ANDROID_PREFIX ".DeviceId"); -static const QLatin1String AndroidProFileKey(ANDROID_PREFIX ".ProFile"); -static const QLatin1String AndroidExportedLocalDirsKey(ANDROID_PREFIX ".ExportedLocalDirs"); -static const QLatin1String AndroidBaseEnvironmentBaseKey(ANDROID_PREFIX ".BaseEnvironmentBase"); -static const QLatin1String AndroidUserEnvironmentChangesKey(ANDROID_PREFIX ".UserEnvironmentChanges"); -static const QLatin1String AndroidUseRemoteGdbKey(ANDROID_PREFIX ".UseRemoteGdb"); - } // namespace Internal namespace Constants { @@ -77,8 +67,6 @@ const char ANDROID_SETTINGS_TR_CATEGORY[] = QT_TRANSLATE_NOOP("Android", "Androi const char ANDROID_SETTINGS_CATEGORY_ICON[] = ":/android/images/QtAndroid.png"; const char ANDROID_TOOLCHAIN_ID[] = "Qt4ProjectManager.ToolChain.Android"; const char ANDROIDQT[] = "Qt4ProjectManager.QtVersion.Android"; -const char ANDROID_PLATFORM[] = "Android"; -const char ANDROID_PLATFORM_TR[] = QT_TRANSLATE_NOOP("QtSupport", "Android"); } } // namespace Android diff --git a/src/plugins/android/androidcreatekeystorecertificate.cpp b/src/plugins/android/androidcreatekeystorecertificate.cpp index 8a326c3b59c..a542f7f4d0e 100644 --- a/src/plugins/android/androidcreatekeystorecertificate.cpp +++ b/src/plugins/android/androidcreatekeystorecertificate.cpp @@ -56,7 +56,7 @@ AndroidCreateKeystoreCertificate::~AndroidCreateKeystoreCertificate() delete ui; } -QString AndroidCreateKeystoreCertificate::keystoreFilePath() +Utils::FileName AndroidCreateKeystoreCertificate::keystoreFilePath() { return m_keystoreFilePath; } @@ -155,10 +155,10 @@ void AndroidCreateKeystoreCertificate::on_buttonBox_accepted() if (!ui->countryLineEdit->text().length()) ui->countryLineEdit->setFocus(); - m_keystoreFilePath = QFileDialog::getSaveFileName(this, tr("Keystore file name"), - QDir::homePath() + QLatin1String("/android_release.keystore"), - tr("Keystore files (*.keystore *.jks)")); - if (!m_keystoreFilePath.length()) + m_keystoreFilePath = Utils::FileName::fromString(QFileDialog::getSaveFileName(this, tr("Keystore file name"), + QDir::homePath() + QLatin1String("/android_release.keystore"), + tr("Keystore files (*.keystore *.jks)"))); + if (m_keystoreFilePath.isEmpty()) return; QString distinguishedNames(QString::fromLatin1("CN=%1, O=%2, L=%3, C=%4") .arg(ui->commonNameLineEdit->text().replace(QLatin1Char(','), QLatin1String("\\,"))) @@ -174,7 +174,7 @@ void AndroidCreateKeystoreCertificate::on_buttonBox_accepted() QStringList params; params << QLatin1String("-genkey") << QLatin1String("-keyalg") << QLatin1String("RSA") - << QLatin1String("-keystore") << m_keystoreFilePath + << QLatin1String("-keystore") << m_keystoreFilePath.toString() << QLatin1String("-storepass") << ui->keystorePassLineEdit->text() << QLatin1String("-alias") << ui->aliasNameLineEdit->text() << QLatin1String("-keysize") << ui->keySizeSpinBox->text() @@ -183,7 +183,7 @@ void AndroidCreateKeystoreCertificate::on_buttonBox_accepted() << QLatin1String("-dname") << distinguishedNames; QProcess genKeyCertProc; - genKeyCertProc.start(AndroidConfigurations::instance().keytoolPath(), params ); + genKeyCertProc.start(AndroidConfigurations::instance().keytoolPath().toString(), params ); if (!genKeyCertProc.waitForStarted() || !genKeyCertProc.waitForFinished()) return; diff --git a/src/plugins/android/androidcreatekeystorecertificate.h b/src/plugins/android/androidcreatekeystorecertificate.h index 9bc89a69162..2a3edb9093f 100644 --- a/src/plugins/android/androidcreatekeystorecertificate.h +++ b/src/plugins/android/androidcreatekeystorecertificate.h @@ -33,6 +33,8 @@ #ifndef ANDROIDCREATEKEYSTORECERTIFICATE_H #define ANDROIDCREATEKEYSTORECERTIFICATE_H +#include <utils/fileutils.h> + #include <QDialog> QT_BEGIN_NAMESPACE @@ -54,7 +56,7 @@ class AndroidCreateKeystoreCertificate : public QDialog public: explicit AndroidCreateKeystoreCertificate(QWidget *parent = 0); ~AndroidCreateKeystoreCertificate(); - QString keystoreFilePath(); + Utils::FileName keystoreFilePath(); QString keystorePassword(); QString certificateAlias(); QString certificatePassword(); @@ -68,7 +70,7 @@ private slots: private: Ui::AndroidCreateKeystoreCertificate *ui; - QString m_keystoreFilePath; + Utils::FileName m_keystoreFilePath; }; } // namespace Internal diff --git a/src/plugins/android/androiddebugsupport.cpp b/src/plugins/android/androiddebugsupport.cpp index 704ce67c6bc..5eb5150f347 100644 --- a/src/plugins/android/androiddebugsupport.cpp +++ b/src/plugins/android/androiddebugsupport.cpp @@ -35,17 +35,18 @@ #include "androiddeploystep.h" #include "androidglobal.h" #include "androidrunner.h" -#include "androidtarget.h" +#include "androidmanager.h" #include <debugger/debuggerplugin.h> #include <debugger/debuggerrunner.h> #include <debugger/debuggerengine.h> #include <debugger/debuggerstartparameters.h> +#include <projectexplorer/target.h> #include <qt4projectmanager/qt4buildconfiguration.h> -#include <qt4projectmanager/qt4target.h> -#include <qt4projectmanager/qt4project.h> #include <qt4projectmanager/qt4nodes.h> +#include <qt4projectmanager/qt4project.h> +#include <qtsupport/qtprofileinformation.h> #include <QDir> @@ -62,6 +63,8 @@ static const char * const qMakeVariables[] = { "QT_INSTALL_IMPORTS" }; +static Qt4Project *project(AndroidRunConfiguration *rc) +{ return static_cast<Qt4Project *>(rc->target()->project()); } RunControl *AndroidDebugSupport::createDebugRunControl(AndroidRunConfiguration *runConfig) { @@ -69,19 +72,20 @@ RunControl *AndroidDebugSupport::createDebugRunControl(AndroidRunConfiguration * params.toolChainAbi = runConfig->abi(); params.dumperLibrary = runConfig->dumperLib(); params.startMode = AttachToRemoteServer; - params.executable = runConfig->androidTarget()->qt4Project()->rootQt4ProjectNode()->buildDir() + QLatin1String("/app_process"); - params.debuggerCommand = runConfig->gdbCmd(); + params.executable = project(runConfig)->rootQt4ProjectNode()->buildDir() + QLatin1String("/app_process"); + params.debuggerCommand = runConfig->gdbCmd().toString(); params.remoteChannel = runConfig->remoteChannel(); - params.displayName = runConfig->androidTarget()->packageName(); + params.displayName = AndroidManager::packageName(runConfig->target()); params.solibSearchPath.clear(); - QList<Qt4ProFileNode *> nodes = runConfig->androidTarget()->qt4Project()->allProFiles(); + QList<Qt4ProFileNode *> nodes = project(runConfig)->allProFiles(); foreach (Qt4ProFileNode *node, nodes) if (node->projectType() == ApplicationTemplate) params.solibSearchPath.append(node->targetInformation().buildDir); - params.solibSearchPath.append(qtSoPaths(runConfig->activeQt4BuildConfiguration()->qtVersion())); + QtSupport::BaseQtVersion *version = QtSupport::QtProfileInformation::qtVersion(runConfig->target()->profile()); + params.solibSearchPath.append(qtSoPaths(version)); params.useServerStartScript = true; params.remoteSetupNeeded = true; @@ -148,6 +152,9 @@ void AndroidDebugSupport::handleRemoteErrorOutput(const QByteArray &output) QStringList AndroidDebugSupport::qtSoPaths(QtSupport::BaseQtVersion *qtVersion) { + if (!qtVersion) + return QStringList(); + QSet<QString> paths; for (uint i = 0; i < sizeof qMakeVariables / sizeof qMakeVariables[0]; ++i) { if (!qtVersion->versionInfo().contains(QLatin1String(qMakeVariables[i]))) diff --git a/src/plugins/android/androiddeployconfiguration.cpp b/src/plugins/android/androiddeployconfiguration.cpp index 0efd9a46c0b..c07219b7932 100644 --- a/src/plugins/android/androiddeployconfiguration.cpp +++ b/src/plugins/android/androiddeployconfiguration.cpp @@ -34,13 +34,14 @@ #include "androidpackageinstallationstep.h" #include "androidpackagecreationstep.h" #include "androiddeployconfiguration.h" -#include "androidtarget.h" +#include "androidmanager.h" #include <projectexplorer/buildsteplist.h> #include <projectexplorer/target.h> -#include <qt4projectmanager/qt4projectmanagerconstants.h> #include <qt4projectmanager/qt4project.h> +#include <qtsupport/qtprofileinformation.h> +#include <qtsupport/qtsupportconstants.h> using namespace Android::Internal; @@ -64,15 +65,11 @@ AndroidDeployConfiguration::AndroidDeployConfiguration(ProjectExplorer::Target * AndroidDeployConfigurationFactory::AndroidDeployConfigurationFactory(QObject *parent) : ProjectExplorer::DeployConfigurationFactory(parent) -{ } +{ setObjectName(QLatin1String("AndroidDeployConfigurationFactory"));} bool AndroidDeployConfigurationFactory::canCreate(ProjectExplorer::Target *parent, const Core::Id id) const { - AndroidTarget *t = qobject_cast<AndroidTarget *>(parent); - if (!t || t->id() != Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID) - || !id.toString().startsWith(QLatin1String(ANDROID_DEPLOYCONFIGURATION_ID))) - return false; - return true; + return availableCreationIds(parent).contains(id); } ProjectExplorer::DeployConfiguration *AndroidDeployConfigurationFactory::create(ProjectExplorer::Target *parent, const Core::Id id) @@ -96,8 +93,7 @@ ProjectExplorer::DeployConfiguration *AndroidDeployConfigurationFactory::restore { if (!canRestore(parent, map)) return 0; - AndroidTarget *t = static_cast<AndroidTarget *>(parent); - AndroidDeployConfiguration *dc = new AndroidDeployConfiguration(t); + AndroidDeployConfiguration *dc = new AndroidDeployConfiguration(parent); if (dc->fromMap(map)) return dc; @@ -107,7 +103,7 @@ ProjectExplorer::DeployConfiguration *AndroidDeployConfigurationFactory::restore bool AndroidDeployConfigurationFactory::canClone(ProjectExplorer::Target *parent, ProjectExplorer::DeployConfiguration *source) const { - if (!qobject_cast<AndroidTarget *>(parent)) + if (!AndroidManager::supportsAndroid(parent)) return false; return source->id() == Core::Id(ANDROID_DEPLOYCONFIGURATION_ID); } @@ -116,24 +112,24 @@ ProjectExplorer::DeployConfiguration *AndroidDeployConfigurationFactory::clone(P { if (!canClone(parent, source)) return 0; - AndroidTarget *t = static_cast<AndroidTarget *>(parent); - return new AndroidDeployConfiguration(t, source); + return new AndroidDeployConfiguration(parent, source); } QList<Core::Id> AndroidDeployConfigurationFactory::availableCreationIds(ProjectExplorer::Target *parent) const { - AndroidTarget *target = qobject_cast<AndroidTarget *>(parent); - if (!target || - target->id() != Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID)) + if (!AndroidManager::supportsAndroid(parent)) return QList<Core::Id>(); QList<Core::Id> result; - foreach (const QString &id, target->qt4Project()->applicationProFilePathes(QLatin1String(ANDROID_DC_PREFIX))) + Qt4ProjectManager::Qt4Project *project = static_cast<Qt4ProjectManager::Qt4Project *>(parent->project()); + foreach (const QString &id, project->applicationProFilePathes(QLatin1String(ANDROID_DC_PREFIX))) result << Core::Id(id.toUtf8().constData()); return result; } -QString AndroidDeployConfigurationFactory::displayNameForId(const Core::Id/*id*/) const +QString AndroidDeployConfigurationFactory::displayNameForId(const Core::Id id) const { - return tr("Deploy on Android"); + if (id.toString().startsWith(ANDROID_DC_PREFIX)) + return tr("Deploy on Android"); + return QString(); } diff --git a/src/plugins/android/androiddeployconfiguration.h b/src/plugins/android/androiddeployconfiguration.h index 5a08c4f8ee3..546470076c0 100644 --- a/src/plugins/android/androiddeployconfiguration.h +++ b/src/plugins/android/androiddeployconfiguration.h @@ -72,7 +72,6 @@ public: QList<Core::Id> availableCreationIds(ProjectExplorer::Target *parent) const; // used to translate the ids to names to display to the user QString displayNameForId(const Core::Id id) const; - }; } // namespace Internal diff --git a/src/plugins/android/androiddeploystep.cpp b/src/plugins/android/androiddeploystep.cpp index 57b6d9d1c80..3cbd1cbea3d 100644 --- a/src/plugins/android/androiddeploystep.cpp +++ b/src/plugins/android/androiddeploystep.cpp @@ -37,16 +37,16 @@ #include "androidglobal.h" #include "androidpackagecreationstep.h" #include "androidrunconfiguration.h" -#include "androidtarget.h" +#include "androidmanager.h" #include <projectexplorer/buildconfiguration.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/target.h> +#include <qt4projectmanager/qt4buildconfiguration.h> #include <qt4projectmanager/qt4project.h> -#include <qt4projectmanager/qt4target.h> #include <qt4projectmanager/qt4nodes.h> -#include <qt4projectmanager/qt4buildconfiguration.h> +#include <qtsupport/qtprofileinformation.h> #include <QDir> @@ -85,14 +85,8 @@ void AndroidDeployStep::ctor() bool AndroidDeployStep::init() { - AndroidTarget *androidTarget = qobject_cast<AndroidTarget *>(target()); - if (!androidTarget) { - raiseError(tr("Cannot deploy: current target is not android.")); - return false; - } - const Qt4BuildConfiguration *const bc = androidTarget->activeQt4BuildConfiguration(); - m_packageName = androidTarget->packageName(); - const QString targetSDK = androidTarget->targetSDK(); + m_packageName = AndroidManager::packageName(target()); + const QString targetSDK = AndroidManager::targetSDK(target()); writeOutput(tr("Please wait, searching for a suitable device for target:%1.").arg(targetSDK)); m_deviceAPILevel = targetSDK.mid(targetSDK.indexOf(QLatin1Char('-')) + 1).toInt(); @@ -103,14 +97,15 @@ bool AndroidDeployStep::init() return false; } - if (!bc->qtVersion()) + QtSupport::BaseQtVersion *version = QtSupport::QtProfileInformation::qtVersion(target()->profile()); + if (!version) return false; - m_qtVersionSourcePath = bc->qtVersion()->sourcePath().toString(); - m_qtVersionQMakeBuildConfig = bc->qtVersion()->defaultBuildConfig(); - m_androidDirPath = androidTarget->androidDirPath(); - m_apkPathDebug = androidTarget->apkPath(AndroidTarget::DebugBuild); - m_apkPathRelease = androidTarget->apkPath(AndroidTarget::ReleaseBuildSigned); - m_buildDirectory = androidTarget->qt4Project()->rootQt4ProjectNode()->buildDir(); + m_qtVersionSourcePath = version->sourcePath().toString(); + m_qtVersionQMakeBuildConfig = version->defaultBuildConfig(); + m_androidDirPath = AndroidManager::dirPath(target()); + m_apkPathDebug = AndroidManager::apkPath(target(), AndroidManager::DebugBuild).toString(); + m_apkPathRelease = AndroidManager::apkPath(target(), AndroidManager::ReleaseBuildSigned).toString(); + m_buildDirectory = static_cast<Qt4Project *>(target()->project())->rootQt4ProjectNode()->buildDir(); m_runQASIPackagePath = m_QASIPackagePath; m_runDeployAction = m_deployAction; return true; @@ -205,12 +200,9 @@ int AndroidDeployStep::deviceAPILevel() return m_deviceAPILevel; } -QString AndroidDeployStep::localLibsRulesFilePath() +Utils::FileName AndroidDeployStep::localLibsRulesFilePath() { - AndroidTarget *androidTarget = qobject_cast<AndroidTarget *>(target()); - if (!androidTarget) - return QString(); - return androidTarget->localLibsRulesFilePath(); + return AndroidManager::localLibsRulesFilePath(target()); } void AndroidDeployStep::copyLibs(const QString &srcPath, const QString &destPath, QStringList &copiedLibs, const QStringList &filter) @@ -241,7 +233,7 @@ bool AndroidDeployStep::deployPackage() if (m_runDeployAction == DeployLocal) { writeOutput(tr("Clean old qt libs")); - runCommand(deployProc, AndroidConfigurations::instance().adbToolPath(), + runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(), QStringList() << QLatin1String("-s") << m_deviceSerialNumber << QLatin1String("shell") << QLatin1String("rm") << QLatin1String("-r") << QLatin1String("/data/local/qt")); @@ -258,7 +250,7 @@ bool AndroidDeployStep::deployPackage() copyLibs(m_qtVersionSourcePath + QLatin1String("/jar"), tempPath + QLatin1String("/jar"), stripFiles); AndroidPackageCreationStep::stripAndroidLibs(stripFiles, target()->activeRunConfiguration()->abi().architecture()); - runCommand(deployProc, AndroidConfigurations::instance().adbToolPath(), + runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(), QStringList() << QLatin1String("-s") << m_deviceSerialNumber << QLatin1String("push") << tempPath << QLatin1String("/data/local/qt")); AndroidPackageCreationStep::removeDirectory(tempPath); @@ -266,7 +258,7 @@ bool AndroidDeployStep::deployPackage() } if (m_runDeployAction == InstallQASI) { - if (!runCommand(deployProc, AndroidConfigurations::instance().adbToolPath(), + if (!runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(), QStringList() << QLatin1String("-s") << m_deviceSerialNumber << QLatin1String("install") << QLatin1String("-r ") << m_runQASIPackagePath)) { raiseError(tr("Qt Android smart installer instalation failed")); @@ -276,10 +268,10 @@ bool AndroidDeployStep::deployPackage() } emit resetDelopyAction(); } - deployProc->setWorkingDirectory(m_androidDirPath); + deployProc->setWorkingDirectory(m_androidDirPath.toString()); writeOutput(tr("Installing package onto %1.").arg(m_deviceSerialNumber)); - runCommand(deployProc, AndroidConfigurations::instance().adbToolPath(), + runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(), QStringList() << QLatin1String("-s") << m_deviceSerialNumber << QLatin1String("uninstall") << m_packageName); QString package = m_apkPathDebug; @@ -287,7 +279,7 @@ bool AndroidDeployStep::deployPackage() && QFile::exists(m_apkPathRelease)) package = m_apkPathRelease; - if (!runCommand(deployProc, AndroidConfigurations::instance().adbToolPath(), + if (!runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(), QStringList() << QLatin1String("-s") << m_deviceSerialNumber << QLatin1String("install") << package)) { raiseError(tr("Package instalation failed")); disconnect(deployProc, 0, this, 0); @@ -296,11 +288,11 @@ bool AndroidDeployStep::deployPackage() } writeOutput(tr("Pulling files necessary for debugging")); - runCommand(deployProc, AndroidConfigurations::instance().adbToolPath(), + runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(), QStringList() << QLatin1String("-s") << m_deviceSerialNumber << QLatin1String("pull") << QLatin1String("/system/bin/app_process") << QString::fromLatin1("%1/app_process").arg(m_buildDirectory)); - runCommand(deployProc, AndroidConfigurations::instance().adbToolPath(), + runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(), QStringList() << QLatin1String("-s") << m_deviceSerialNumber << QLatin1String("pull") << QLatin1String("/system/lib/libc.so") << QString::fromLatin1("%1/libc.so").arg(m_buildDirectory)); diff --git a/src/plugins/android/androiddeploystep.h b/src/plugins/android/androiddeploystep.h index 73553baf84b..f76e248c281 100644 --- a/src/plugins/android/androiddeploystep.h +++ b/src/plugins/android/androiddeploystep.h @@ -70,7 +70,7 @@ public: QString deviceSerialNumber(); int deviceAPILevel(); - QString localLibsRulesFilePath(); + Utils::FileName localLibsRulesFilePath(); AndroidDeployAction deployAction(); bool useLocalQtLibs(); @@ -116,7 +116,7 @@ private: QString m_packageName; QString m_qtVersionSourcePath; QtSupport::BaseQtVersion::QmakeBuildConfigs m_qtVersionQMakeBuildConfig; - QString m_androidDirPath; + Utils::FileName m_androidDirPath; QString m_apkPathDebug; QString m_apkPathRelease; QString m_buildDirectory; diff --git a/src/plugins/android/androiddeploystepfactory.cpp b/src/plugins/android/androiddeploystepfactory.cpp index 4344b69208b..09ffb190c29 100644 --- a/src/plugins/android/androiddeploystepfactory.cpp +++ b/src/plugins/android/androiddeploystepfactory.cpp @@ -33,11 +33,13 @@ #include "androiddeploystepfactory.h" #include "androiddeploystep.h" +#include "androidmanager.h" #include <projectexplorer/buildsteplist.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/target.h> -#include <qt4projectmanager/qt4projectmanagerconstants.h> +#include <qtsupport/qtsupportconstants.h> +#include <qtsupport/qtprofileinformation.h> #include <QCoreApplication> @@ -53,27 +55,25 @@ AndroidDeployStepFactory::AndroidDeployStepFactory(QObject *parent) QList<Core::Id> AndroidDeployStepFactory::availableCreationIds(BuildStepList *parent) const { - if (parent->id() == Core::Id(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY) - && parent->target()->id() == Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID) - && !parent->contains(AndroidDeployStep::Id)) - return QList<Core::Id>() << AndroidDeployStep::Id; - return QList<Core::Id>(); + if (parent->id() != Core::Id(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY)) + return QList<Core::Id>(); + if (!AndroidManager::supportsAndroid(parent->target())) + return QList<Core::Id>(); + if (parent->contains(AndroidDeployStep::Id)) + return QList<Core::Id>(); + return QList<Core::Id>() << AndroidDeployStep::Id; } QString AndroidDeployStepFactory::displayNameForId(const Core::Id id) const { if (id == AndroidDeployStep::Id) - return QCoreApplication::translate("Qt4ProjectManager::Internal::AndroidDeployStepFactory", - "Deploy to Android device/emulator"); + return tr("Deploy to Android device/emulator"); return QString(); } bool AndroidDeployStepFactory::canCreate(BuildStepList *parent, const Core::Id id) const { - return parent->id() == Core::Id(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY) - && id == Core::Id(AndroidDeployStep::Id) - && parent->target()->id() == Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID) - && !parent->contains(AndroidDeployStep::Id); + return availableCreationIds(parent).contains(id); } BuildStep *AndroidDeployStepFactory::create(BuildStepList *parent, const Core::Id id) diff --git a/src/plugins/android/androiddeploystepwidget.cpp b/src/plugins/android/androiddeploystepwidget.cpp index 9dce27ce618..cd8616ed8cd 100644 --- a/src/plugins/android/androiddeploystepwidget.cpp +++ b/src/plugins/android/androiddeploystepwidget.cpp @@ -110,7 +110,7 @@ void AndroidDeployStepWidget::useLocalQtLibsStateChanged(int state) void AndroidDeployStepWidget::editRulesFile() { - Core::ICore::instance()->openFiles(QStringList() << m_step->localLibsRulesFilePath(), Core::ICore::SwitchMode); + Core::ICore::instance()->openFiles(QStringList() << m_step->localLibsRulesFilePath().toString(), Core::ICore::SwitchMode); } } // namespace Internal diff --git a/src/plugins/android/androidtarget.cpp b/src/plugins/android/androidmanager.cpp index 7367c9645c4..b95c2bdb3f4 100644 --- a/src/plugins/android/androidtarget.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -30,7 +30,7 @@ ** **************************************************************************/ -#include "androidtarget.h" +#include "androidmanager.h" #include "androiddeployconfiguration.h" #include "androidconfigurations.h" #include "androidrunconfiguration.h" @@ -38,12 +38,16 @@ #include "androidglobal.h" #include "androidpackagecreationstep.h" +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/session.h> +#include <projectexplorer/target.h> #include <qt4projectmanager/qt4nodes.h> #include <qt4projectmanager/qt4project.h> #include <qt4projectmanager/qt4projectmanagerconstants.h> -#include <qt4projectmanager/qt4target.h> #include <qt4projectmanager/qt4buildconfiguration.h> #include <qtsupport/customexecutablerunconfiguration.h> +#include <qtsupport/qtprofileinformation.h> +#include <qtsupport/qtsupportconstants.h> #include <QDir> #include <QFileSystemWatcher> @@ -53,9 +57,6 @@ #include <QApplication> #include <QDomDocument> -using namespace ProjectExplorer; -using namespace Qt4ProjectManager; - namespace { const QLatin1String AndroidDirName("android"); const QLatin1String AndroidManifestName("AndroidManifest.xml"); @@ -78,499 +79,263 @@ namespace { namespace Android { namespace Internal { -AndroidTarget::AndroidTarget(Qt4Project *parent, const Core::Id id) : - Qt4BaseTarget(parent, id) - , m_androidFilesWatcher(new QFileSystemWatcher(this)) - , m_buildConfigurationFactory(new Qt4BuildConfigurationFactory(this)) -{ - setDisplayName(defaultDisplayName()); - setDefaultDisplayName(defaultDisplayName()); - setIcon(QIcon(QLatin1String(Constants::ANDROID_SETTINGS_CATEGORY_ICON))); - connect(parent, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)), - this, SLOT(handleTargetChanged(ProjectExplorer::Target*))); -} +AndroidManager *AndroidManager::m_instance = 0; -AndroidTarget::~AndroidTarget() +AndroidManager *AndroidManager::instance() { - + return m_instance; } -Qt4BuildConfigurationFactory *AndroidTarget::buildConfigurationFactory() const +AndroidManager::~AndroidManager() { - return m_buildConfigurationFactory; } -void AndroidTarget::createApplicationProFiles(bool reparse) +bool AndroidManager::supportsAndroid(ProjectExplorer::Target *target) { - if (!reparse) - removeUnconfiguredCustomExectutableRunConfigurations(); - - QList<Qt4ProFileNode *> profiles = qt4Project()->applicationProFiles(); - QSet<QString> paths; - foreach (Qt4ProFileNode *pro, profiles) - paths << pro->path(); - - foreach (ProjectExplorer::RunConfiguration *rc, runConfigurations()) - if (AndroidRunConfiguration *qt4rc = qobject_cast<AndroidRunConfiguration *>(rc)) - paths.remove(qt4rc->proFilePath()); - - // Only add new runconfigurations if there are none. - foreach (const QString &path, paths) - addRunConfiguration(new AndroidRunConfiguration(this, path)); - - // Oh still none? Add a custom executable runconfiguration - if (runConfigurations().isEmpty()) { - addRunConfiguration(new QtSupport::CustomExecutableRunConfiguration(this)); - } -} - -QList<ProjectExplorer::RunConfiguration *> AndroidTarget::runConfigurationsForNode(ProjectExplorer::Node *n) -{ - QList<ProjectExplorer::RunConfiguration *> result; - foreach (ProjectExplorer::RunConfiguration *rc, runConfigurations()) - if (AndroidRunConfiguration *qt4c = qobject_cast<AndroidRunConfiguration *>(rc)) - if (qt4c->proFilePath() == n->path()) - result << rc; - return result; + if (!qobject_cast<Qt4ProjectManager::Qt4Project *>(target->project())) + return false; + QtSupport::BaseQtVersion *version = QtSupport::QtProfileInformation::qtVersion(target->profile()); + return version && version->platformName() == QtSupport::Constants::ANDROID_PLATFORM; } -QString AndroidTarget::defaultDisplayName() +QString AndroidManager::packageName(ProjectExplorer::Target *target) { - return QApplication::translate("Qt4ProjectManager::Qt4Target", "Android", "Qt4 Android target display name"); + QDomDocument doc; + if (!openManifest(target, doc)) + return QString(); + QDomElement manifestElem = doc.documentElement(); + return manifestElem.attribute(QLatin1String("package")); } -void AndroidTarget::handleTargetChanged(ProjectExplorer::Target *target) +bool AndroidManager::setPackageName(ProjectExplorer::Target *target, const QString &name) { - if (target != this) - return; - - disconnect(project(), SIGNAL(addedTarget(ProjectExplorer::Target*)), - this, SLOT(handleTargetChanged(ProjectExplorer::Target*))); - connect(project(), SIGNAL(aboutToRemoveTarget(ProjectExplorer::Target*)), - SLOT(handleTargetToBeRemoved(ProjectExplorer::Target*))); - - if (!createAndroidTemplatesIfNecessary()) - return; - - m_androidFilesWatcher->addPath(androidDirPath()); - m_androidFilesWatcher->addPath(androidManifestPath()); - m_androidFilesWatcher->addPath(androidSrcPath()); - connect(m_androidFilesWatcher, SIGNAL(directoryChanged(QString)), this, - SIGNAL(androidDirContentsChanged())); - connect(m_androidFilesWatcher, SIGNAL(fileChanged(QString)), this, - SIGNAL(androidDirContentsChanged())); + QDomDocument doc; + if (!openManifest(target, doc)) + return false; + QDomElement manifestElem = doc.documentElement(); + manifestElem.setAttribute(QLatin1String("package"), cleanPackageName(name)); + return saveManifest(target, doc); } -void AndroidTarget::handleTargetToBeRemoved(ProjectExplorer::Target *target) +QString AndroidManager::applicationName(ProjectExplorer::Target *target) { - if (target != this) - return; - -// I don't think is a good idea to remove android directory - -// const QString debianPath = debianDirPath(); -// if (!QFileInfo(debianPath).exists()) -// return; -// const int answer = QMessageBox::warning(0, tr("Qt Creator"), -// tr("Do you want to remove the packaging directory\n" -// "associated with the target '%1'?").arg(displayName()), -// QMessageBox::Yes | QMessageBox::No, QMessageBox::No); -// if (answer == QMessageBox::No) -// return; -// QString error; -// if (!MaemoGlobal::removeRecursively(debianPath, error)) -// qDebug("%s", qPrintable(error)); -// const QString packagingPath = project()->projectDirectory() -// + QLatin1Char('/') + PackagingDirName; -// const QStringList otherContents = QDir(packagingPath).entryList(QDir::Dirs -// | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot); -// if (otherContents.isEmpty()) { -// if (!MaemoGlobal::removeRecursively(packagingPath, error)) -// qDebug("%s", qPrintable(error)); -// } + QDomDocument doc; + if (!openXmlFile(target, doc, stringsPath(target))) + return QString(); + QDomElement metadataElem = doc.documentElement().firstChildElement(QLatin1String("string")); + while (!metadataElem.isNull()) { + if (metadataElem.attribute(QLatin1String("name")) == QLatin1String("app_name")) + return metadataElem.text(); + metadataElem = metadataElem.nextSiblingElement(QLatin1String("string")); + } + return QString(); } -QString AndroidTarget::androidDirPath() const +bool AndroidManager::setApplicationName(ProjectExplorer::Target *target, const QString &name) { - return project()->projectDirectory() + QLatin1Char('/') + AndroidDirName; + QDomDocument doc; + Utils::FileName path = stringsPath(target); + if (!openXmlFile(target, doc, path)) + return false; + QDomElement metadataElem = doc.documentElement().firstChildElement(QLatin1String("string")); + while (!metadataElem.isNull()) { + if (metadataElem.attribute(QLatin1String("name")) == QLatin1String("app_name")) { + metadataElem.removeChild(metadataElem.firstChild()); + metadataElem.appendChild(doc.createTextNode(name)); + break; + } + metadataElem = metadataElem.nextSiblingElement(QLatin1String("string")); + } + return saveXmlFile(target, doc, path); } -QString AndroidTarget::androidManifestPath() const +QStringList AndroidManager::permissions(ProjectExplorer::Target *target) { - return androidDirPath() + QLatin1Char('/') + AndroidManifestName; + QStringList per; + QDomDocument doc; + if (!openManifest(target, doc)) + return per; + QDomElement permissionElem = doc.documentElement().firstChildElement(QLatin1String("uses-permission")); + while (!permissionElem.isNull()) { + per << permissionElem.attribute(QLatin1String("android:name")); + permissionElem = permissionElem.nextSiblingElement(QLatin1String("uses-permission")); + } + return per; } -QString AndroidTarget::androidLibsPath() const +bool AndroidManager::setPermissions(ProjectExplorer::Target *target, const QStringList &permissions) { - return androidDirPath() + AndroidLibsFileName; -} + QDomDocument doc; + if (!openManifest(target, doc)) + return false; + QDomElement docElement = doc.documentElement(); + QDomElement permissionElem = docElement.firstChildElement(QLatin1String("uses-permission")); + while (!permissionElem.isNull()) { + docElement.removeChild(permissionElem); + permissionElem = docElement.firstChildElement(QLatin1String("uses-permission")); + } -QString AndroidTarget::androidStringsPath() const -{ - return androidDirPath() + AndroidStringsFileName; -} + foreach (const QString &permission, permissions ) { + permissionElem = doc.createElement(QLatin1String("uses-permission")); + permissionElem.setAttribute(QLatin1String("android:name"), permission); + docElement.appendChild(permissionElem); + } -QString AndroidTarget::androidDefaultPropertiesPath() const -{ - return androidDirPath() + QLatin1Char('/') + AndroidDefaultPropertiesName; + return saveManifest(target, doc); } -QString AndroidTarget::androidSrcPath() const +QString AndroidManager::intentName(ProjectExplorer::Target *target) { - return androidDirPath() + QLatin1String("/src"); + return packageName(target) + QLatin1Char('/') + activityName(target); } -QString AndroidTarget::apkPath(BuildType buildType) const +QString AndroidManager::activityName(ProjectExplorer::Target *target) { - return project()->projectDirectory() + QLatin1Char('/') - + AndroidDirName - + QString::fromLatin1("/bin/%1-%2.apk") - .arg(applicationName()) - .arg(buildType == DebugBuild ? QLatin1String("debug") - : (buildType == ReleaseBuildUnsigned) ? QLatin1String("release-unsigned") - : QLatin1String("signed")); + QDomDocument doc; + if (!openManifest(target, doc)) + return QString(); + QDomElement activityElem = doc.documentElement().firstChildElement(QLatin1String("application")).firstChildElement(QLatin1String("activity")); + return activityElem.attribute(QLatin1String("android:name")); } -QString AndroidTarget::localLibsRulesFilePath() const +int AndroidManager::versionCode(ProjectExplorer::Target *target) { - const Qt4Project *const qt4Project = qobject_cast<const Qt4Project *>(project()); - if (!qt4Project || !qt4Project->activeTarget()->activeQt4BuildConfiguration()->qtVersion()) - return QLatin1String(""); - - return qt4Project->activeTarget()->activeQt4BuildConfiguration() - ->qtVersion()->versionInfo()[QLatin1String("QT_INSTALL_LIBS")] + QLatin1String("/rules.xml"); + QDomDocument doc; + if (!openManifest(target, doc)) + return 0; + QDomElement manifestElem = doc.documentElement(); + return manifestElem.attribute(QLatin1String("android:versionCode")).toInt(); } -QString AndroidTarget::loadLocal(int apiLevel, ItemType item) const +bool AndroidManager::setVersionCode(ProjectExplorer::Target *target, int version) { - QString itemType; - if (item == Lib) - itemType = QLatin1String("lib"); - else - itemType = QLatin1String("jar"); - - QString localLibs; - QDomDocument doc; - if (!openXmlFile(doc, localLibsRulesFilePath())) - return localLibs; - - QStringList libs; - libs << qtLibs() << prebundledLibs(); - QDomElement element = doc.documentElement().firstChildElement(QLatin1String("platforms")).firstChildElement(itemType + QLatin1Char('s')).firstChildElement(QLatin1String("version")); - while (!element.isNull()) { - if (element.attribute(QLatin1String("value")).toInt() == apiLevel) { - if (element.hasAttribute(QLatin1String("symlink"))) - apiLevel = element.attribute(QLatin1String("symlink")).toInt(); - break; - } - element = element.nextSiblingElement(QLatin1String("version")); - } - - element = doc.documentElement().firstChildElement(QLatin1String("dependencies")).firstChildElement(QLatin1String("lib")); - while (!element.isNull()) { - if (libs.contains(element.attribute(QLatin1String("name")))) { - QDomElement libElement = element.firstChildElement(QLatin1String("depends")).firstChildElement(itemType); - while (!libElement.isNull()) { - localLibs += libElement.attribute(QLatin1String("file")).arg(apiLevel) + QLatin1Char(':'); - libElement = libElement.nextSiblingElement(itemType); - } - - libElement = element.firstChildElement(QLatin1String("replaces")).firstChildElement(itemType); - while (!libElement.isNull()) { - localLibs.replace(libElement.attribute(QLatin1String("file")).arg(apiLevel) + QLatin1Char(':'), QString()); - libElement = libElement.nextSiblingElement(itemType); - } - } - element = element.nextSiblingElement(QLatin1String("lib")); - } - return localLibs; + if (!openManifest(target, doc)) + return false; + QDomElement manifestElem = doc.documentElement(); + manifestElem.setAttribute(QLatin1String("android:versionCode"), version); + return saveManifest(target, doc); } -QString AndroidTarget::loadLocalLibs(int apiLevel) const +QString AndroidManager::versionName(ProjectExplorer::Target *target) { - return loadLocal(apiLevel, Lib); + QDomDocument doc; + if (!openManifest(target, doc)) + return QString(); + QDomElement manifestElem = doc.documentElement(); + return manifestElem.attribute(QLatin1String("android:versionName")); } -QString AndroidTarget::loadLocalJars(int apiLevel) const +bool AndroidManager::setVersionName(ProjectExplorer::Target *target, const QString &version) { - return loadLocal(apiLevel, Jar); + QDomDocument doc; + if (!openManifest(target, doc)) + return false; + QDomElement manifestElem = doc.documentElement(); + manifestElem.setAttribute(QLatin1String("android:versionName"), version); + return saveManifest(target, doc); } -void AndroidTarget::updateProject(const QString &targetSDK, const QString &name) const +QString AndroidManager::targetSDK(ProjectExplorer::Target *target) { - QString androidDir = androidDirPath(); - - // clean previous build - QProcess androidProc; - androidProc.setWorkingDirectory(androidDir); - androidProc.start(AndroidConfigurations::instance().antToolPath(), QStringList() << QLatin1String("clean")); - if (!androidProc.waitForFinished(-1)) - androidProc.terminate(); - // clean previous build - - int targetSDKNumber = targetSDK.mid(targetSDK.lastIndexOf(QLatin1Char('-')) + 1).toInt(); - bool commentLines = false; - QDirIterator it(androidDir, QStringList() << QLatin1String("*.java"), QDir::Files, QDirIterator::Subdirectories); - while (it.hasNext()) { - it.next(); - QFile file(it.filePath()); - if (!file.open(QIODevice::ReadWrite)) - continue; - QList<QByteArray> lines = file.readAll().trimmed().split('\n'); - - bool modified = false; - bool comment = false; - for (int i = 0; i < lines.size(); i++) { - if (lines[i].contains("@ANDROID-")) { - commentLines = targetSDKNumber < lines[i].mid(lines[i].lastIndexOf('-') + 1).toInt(); - comment = !comment; - continue; - } - if (!comment) - continue; - if (commentLines) { - if (!lines[i].trimmed().startsWith("//QtCreator")) { - lines[i] = "//QtCreator " + lines[i]; - modified = true; - } - } else { if (lines[i].trimmed().startsWith("//QtCreator")) { - lines[i] = lines[i].mid(12); - modified = true; - } - } - } - if (modified) { - file.resize(0); - foreach (const QByteArray &line, lines) { - file.write(line); - file.write("\n"); - } - } - file.close(); + if (!createAndroidTemplatesIfNecessary(target)) + return AndroidConfigurations::instance().bestMatch(QLatin1String("android-8")); + QFile file(defaultPropertiesPath(target).toString()); + if (!file.open(QIODevice::ReadOnly)) + return AndroidConfigurations::instance().bestMatch(QLatin1String("android-8")); + while (!file.atEnd()) { + QByteArray line = file.readLine(); + if (line.startsWith("target=")) + return QString::fromLatin1(line.trimmed().mid(7)); } - - QStringList params; - params << QLatin1String("update") << QLatin1String("project") << QLatin1String("-p") << androidDir; - if (!targetSDK.isEmpty()) - params << QLatin1String("-t") << targetSDK; - if (!name.isEmpty()) - params << QLatin1String("-n") << name; - androidProc.start(AndroidConfigurations::instance().androidToolPath(), params); - if (!androidProc.waitForFinished(-1)) - androidProc.terminate(); + return AndroidConfigurations::instance().bestMatch(QLatin1String("android-8")); } -bool AndroidTarget::createAndroidTemplatesIfNecessary() const +bool AndroidManager::setTargetSDK(ProjectExplorer::Target *target, const QString &sdk) { - const Qt4Project *qt4Project = qobject_cast<Qt4Project*>(project()); - if (!qt4Project || !qt4Project->rootProjectNode() || !qt4Project->activeTarget() || !qt4Project->activeTarget()->activeQt4BuildConfiguration() - || !qt4Project->activeTarget()->activeQt4BuildConfiguration()->qtVersion()) - return false; - QString javaSrcPath = qt4Project->activeTarget()->activeQt4BuildConfiguration()->qtVersion()->versionInfo()[QLatin1String("QT_INSTALL_PREFIX")] + QLatin1String("/src/android/java"); - QDir projectDir(project()->projectDirectory()); - QString androidPath = androidDirPath(); - - QStringList m_ignoreFiles; - bool forceUpdate = false; - QDomDocument srcVersionDoc; - if (openXmlFile(srcVersionDoc, javaSrcPath + QLatin1String("/version.xml"), false)) { - QDomDocument dstVersionDoc; - if (openXmlFile(dstVersionDoc, androidPath + QLatin1String("/version.xml"), false)) - forceUpdate = (srcVersionDoc.documentElement().attribute(QLatin1String("value")).toDouble() - > dstVersionDoc.documentElement().attribute(QLatin1String("value")).toDouble()); - - else - forceUpdate = true; - - if (forceUpdate && QFileInfo(androidPath).exists()) { - QDomElement ignoreFile = srcVersionDoc.documentElement().firstChildElement(QLatin1String("ignore")).firstChildElement(QLatin1String("file")); - while (!ignoreFile.isNull()) { - m_ignoreFiles << ignoreFile.text(); - ignoreFile = ignoreFile.nextSiblingElement(); - } - } - } - - if (!forceUpdate && QFileInfo(androidPath).exists() - && QFileInfo(androidManifestPath()).exists() - && QFileInfo(androidPath + QLatin1String("/src")).exists() - && QFileInfo(androidPath + QLatin1String("/res")).exists()) - return true; - - forceUpdate &= QFileInfo(androidPath).exists(); - - if (!QFileInfo(androidDirPath()).exists() && !projectDir.mkdir(AndroidDirName)) { - raiseError(tr("Error creating Android directory '%1'.") - .arg(AndroidDirName)); - return false; - } - - QStringList androidFiles; - QDirIterator it(javaSrcPath, QDirIterator::Subdirectories); - int pos = it.path().size(); - while (it.hasNext()) { - it.next(); - if (it.fileInfo().isDir()) { - projectDir.mkpath(AndroidDirName + it.filePath().mid(pos)); - } else { - const QString dstFile(androidPath + it.filePath().mid(pos)); - if (m_ignoreFiles.contains(it.fileName())) - continue; - else - { - if (QFile::exists(dstFile)) - QFile::remove(dstFile); - else - androidFiles << dstFile; - } - QFile::copy(it.filePath(), dstFile); - } - } - if (androidFiles.size()) - qt4Project->rootProjectNode()->addFiles(UnknownFileType, androidFiles); - - QStringList sdks = AndroidConfigurations::instance().sdkTargets(); - if (sdks.isEmpty()) { - raiseError(tr("No Qt for Android SDKs were found.\nPlease install at least one SDK.")); - return false; - } - updateProject(AndroidConfigurations::instance().sdkTargets().at(0)); - if (availableTargetApplications().length()) - setTargetApplication(availableTargetApplications()[0]); - - QString applicationName = project()->displayName(); - if (applicationName.length()) { - setPackageName(packageName() + QLatin1Char('.') + applicationName); - applicationName[0] = applicationName[0].toUpper(); - setApplicationName(applicationName); - } - - if (forceUpdate) - QMessageBox::warning(0, tr("Warning"), tr("Android files have been updated automatically")); - + updateTarget(target, sdk, applicationName(target)); return true; } -bool AndroidTarget::openXmlFile(QDomDocument &doc, const QString &fileName, bool createAndroidTemplates) const +QIcon AndroidManager::highDpiIcon(ProjectExplorer::Target *target) { - if (createAndroidTemplates && !createAndroidTemplatesIfNecessary()) - return false; - - QFile f(fileName); - if (!f.open(QIODevice::ReadOnly)) - return false; - - if (!doc.setContent(f.readAll())) { - raiseError(tr("Cannot parse '%1'").arg(fileName)); - return false; - } - return true; + return icon(target, HighDPI); } -bool AndroidTarget::saveXmlFile(QDomDocument &doc, const QString &fileName) const +bool AndroidManager::setHighDpiIcon(ProjectExplorer::Target *target, const QString &iconFilePath) { - if (!createAndroidTemplatesIfNecessary()) - return false; + return setIcon(target, HighDPI, iconFilePath); +} - QFile f(fileName); - if (!f.open(QIODevice::WriteOnly)) { - raiseError(tr("Cannot open '%1'").arg(fileName)); - return false; - } - return f.write(doc.toByteArray(4)) >= 0; +QIcon AndroidManager::mediumDpiIcon(ProjectExplorer::Target *target) +{ + return icon(target, MediumDPI); } -bool AndroidTarget::openAndroidManifest(QDomDocument &doc) const +bool AndroidManager::setMediumDpiIcon(ProjectExplorer::Target *target, const QString &iconFilePath) { - return openXmlFile(doc, androidManifestPath()); + return setIcon(target, MediumDPI, iconFilePath); } -bool AndroidTarget::saveAndroidManifest(QDomDocument &doc) const +QIcon AndroidManager::lowDpiIcon(ProjectExplorer::Target *target) { - return saveXmlFile(doc, androidManifestPath()); + return icon(target, LowDPI); } -bool AndroidTarget::openLibsXml(QDomDocument &doc) const +bool AndroidManager::setLowDpiIcon(ProjectExplorer::Target *target, const QString &iconFilePath) { - return openXmlFile(doc, androidLibsPath()); + return setIcon(target, LowDPI, iconFilePath); } -bool AndroidTarget::saveLibsXml(QDomDocument &doc) const +Utils::FileName AndroidManager::dirPath(ProjectExplorer::Target *target) { - return saveXmlFile(doc, androidLibsPath()); + return Utils::FileName::fromString(target->project()->projectDirectory()).appendPath(AndroidDirName); } -QString AndroidTarget::activityName() const +Utils::FileName AndroidManager::manifestPath(ProjectExplorer::Target *target) { - QDomDocument doc; - if (!openAndroidManifest(doc)) - return QString(); - QDomElement activityElem = doc.documentElement().firstChildElement(QLatin1String("application")).firstChildElement(QLatin1String("activity")); - return activityElem.attribute(QLatin1String("android:name")); + return dirPath(target).appendPath(AndroidManifestName); } -QString AndroidTarget::intentName() const +Utils::FileName AndroidManager::libsPath(ProjectExplorer::Target *target) { - return packageName() + QLatin1Char('/') + activityName(); + return dirPath(target).appendPath(AndroidLibsFileName); } -QString AndroidTarget::packageName() const +Utils::FileName AndroidManager::stringsPath(ProjectExplorer::Target *target) { - QDomDocument doc; - if (!openAndroidManifest(doc)) - return QString(); - QDomElement manifestElem = doc.documentElement(); - return manifestElem.attribute(QLatin1String("package")); + return dirPath(target).append(AndroidStringsFileName); } -bool AndroidTarget::setPackageName(const QString &name) const +Utils::FileName AndroidManager::defaultPropertiesPath(ProjectExplorer::Target *target) { - QDomDocument doc; - if (!openAndroidManifest(doc)) - return false; - QDomElement manifestElem = doc.documentElement(); - manifestElem.setAttribute(QLatin1String("package"), cleanPackageName(name)); - return saveAndroidManifest(doc); + return dirPath(target).appendPath(AndroidDefaultPropertiesName); } -QString AndroidTarget::applicationName() const +Utils::FileName AndroidManager::srcPath(ProjectExplorer::Target *target) { - QDomDocument doc; - if (!openXmlFile(doc, androidStringsPath())) - return QString(); - QDomElement metadataElem = doc.documentElement().firstChildElement(QLatin1String("string")); - while (!metadataElem.isNull()) { - if (metadataElem.attribute(QLatin1String("name")) == QLatin1String("app_name")) - return metadataElem.text(); - metadataElem = metadataElem.nextSiblingElement(QLatin1String("string")); - } - return QString(); + return dirPath(target).appendPath(QLatin1String("/src")); } -bool AndroidTarget::setApplicationName(const QString &name) const +Utils::FileName AndroidManager::apkPath(ProjectExplorer::Target *target, BuildType buildType) { - QDomDocument doc; - if (!openXmlFile(doc, androidStringsPath())) - return false; - QDomElement metadataElem =doc.documentElement().firstChildElement(QLatin1String("string")); - while (!metadataElem.isNull()) { - if (metadataElem.attribute(QLatin1String("name")) == QLatin1String("app_name")) { - metadataElem.removeChild(metadataElem.firstChild()); - metadataElem.appendChild(doc.createTextNode(name)); - break; - } - metadataElem = metadataElem.nextSiblingElement(QLatin1String("string")); - } - return saveXmlFile(doc, androidStringsPath()); + return dirPath(target) + .appendPath(QLatin1String("bin")) + .appendPath(QString::fromLatin1("%1-%2.apk") + .arg(applicationName(target)) + .arg(buildType == DebugBuild + ? QLatin1String("debug") + : (buildType == ReleaseBuildUnsigned) + ? QLatin1String("release-unsigned") + : QLatin1String("signed"))); } -QStringList AndroidTarget::availableTargetApplications() const +QStringList AndroidManager::availableTargetApplications(ProjectExplorer::Target *target) { QStringList apps; - Qt4Project *qt4Project = qobject_cast<Qt4Project *>(project()); - foreach (Qt4ProFileNode *proFile, qt4Project->applicationProFiles()) { - if (proFile->projectType() == ApplicationTemplate) { + Qt4ProjectManager::Qt4Project *qt4Project = qobject_cast<Qt4ProjectManager::Qt4Project *>(target->project()); + foreach (Qt4ProjectManager::Qt4ProFileNode *proFile, qt4Project->applicationProFiles()) { + if (proFile->projectType() == Qt4ProjectManager::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); @@ -582,10 +347,10 @@ QStringList AndroidTarget::availableTargetApplications() const return apps; } -QString AndroidTarget::targetApplication() const +QString AndroidManager::targetApplication(ProjectExplorer::Target *target) { QDomDocument doc; - if (!openAndroidManifest(doc)) + if (!openManifest(target, doc)) return QString(); QDomElement metadataElem = doc.documentElement().firstChildElement(QLatin1String("application")).firstChildElement(QLatin1String("activity")).firstChildElement(QLatin1String("meta-data")); while (!metadataElem.isNull()) { @@ -596,30 +361,30 @@ QString AndroidTarget::targetApplication() const return QString(); } -bool AndroidTarget::setTargetApplication(const QString &name) const +bool AndroidManager::setTargetApplication(ProjectExplorer::Target *target, const QString &name) { QDomDocument doc; - if (!openAndroidManifest(doc)) + if (!openManifest(target, doc)) return false; QDomElement metadataElem = doc.documentElement().firstChildElement(QLatin1String("application")).firstChildElement(QLatin1String("activity")).firstChildElement(QLatin1String("meta-data")); while (!metadataElem.isNull()) { if (metadataElem.attribute(QLatin1String("android:name")) == QLatin1String("android.app.lib_name")) { metadataElem.setAttribute(QLatin1String("android:value"), name); - return saveAndroidManifest(doc); + return saveManifest(target, doc); } metadataElem = metadataElem.nextSiblingElement(QLatin1String("meta-data")); } return false; } -QString AndroidTarget::targetApplicationPath() const +QString AndroidManager::targetApplicationPath(ProjectExplorer::Target *target) { - QString selectedApp = targetApplication(); - if (!selectedApp.length()) + QString selectedApp = targetApplication(target); + if (selectedApp.isEmpty()) return QString(); - Qt4Project *qt4Project = qobject_cast<Qt4Project *>(project()); - foreach (Qt4ProFileNode *proFile, qt4Project->applicationProFiles()) { - if (proFile->projectType() == ApplicationTemplate) { + Qt4ProjectManager::Qt4Project *qt4Project = qobject_cast<Qt4ProjectManager::Qt4Project *>(target->project()); + foreach (Qt4ProjectManager::Qt4ProFileNode *proFile, qt4Project->applicationProFiles()) { + if (proFile->projectType() == Qt4ProjectManager::ApplicationTemplate) { if (proFile->targetInformation().target.startsWith(QLatin1String("lib")) && proFile->targetInformation().target.endsWith(QLatin1String(".so"))) { if (proFile->targetInformation().target.mid(3, proFile->targetInformation().target.lastIndexOf(QLatin1Char('.')) - 3) @@ -634,145 +399,195 @@ QString AndroidTarget::targetApplicationPath() const return QString(); } -int AndroidTarget::versionCode() const +bool AndroidManager::createAndroidTemplatesIfNecessary(ProjectExplorer::Target *target) { - QDomDocument doc; - if (!openAndroidManifest(doc)) - return 0; - QDomElement manifestElem = doc.documentElement(); - return manifestElem.attribute(QLatin1String("android:versionCode")).toInt(); -} - -bool AndroidTarget::setVersionCode(int version) const -{ - QDomDocument doc; - if (!openAndroidManifest(doc)) + QtSupport::BaseQtVersion *version = QtSupport::QtProfileInformation::qtVersion(target->profile()); + Qt4ProjectManager::Qt4Project *qt4Project = qobject_cast<Qt4ProjectManager::Qt4Project*>(target->project()); + if (!qt4Project || !qt4Project->rootProjectNode() || !version) return false; - QDomElement manifestElem = doc.documentElement(); - manifestElem.setAttribute(QLatin1String("android:versionCode"), version); - return saveAndroidManifest(doc); -} + Utils::FileName javaSrcPath + = Utils::FileName::fromString(version->versionInfo()[QLatin1String("QT_INSTALL_PREFIX")]) + .append(QLatin1String("src/android/java")); + QDir projectDir(qt4Project->projectDirectory()); + Utils::FileName androidPath = dirPath(target); -QString AndroidTarget::versionName() const -{ - QDomDocument doc; - if (!openAndroidManifest(doc)) - return QString(); - QDomElement manifestElem = doc.documentElement(); - return manifestElem.attribute(QLatin1String("android:versionName")); -} + QStringList m_ignoreFiles; + bool forceUpdate = false; + QDomDocument srcVersionDoc; + if (openXmlFile(target, srcVersionDoc, javaSrcPath.append(QLatin1String("version.xml")), false)) { + QDomDocument dstVersionDoc; + if (openXmlFile(target, dstVersionDoc, androidPath.append(QLatin1String("version.xml")), false)) + forceUpdate = (srcVersionDoc.documentElement().attribute(QLatin1String("value")).toDouble() + > dstVersionDoc.documentElement().attribute(QLatin1String("value")).toDouble()); + else + forceUpdate = true; -bool AndroidTarget::setVersionName(const QString &version) const -{ - QDomDocument doc; - if (!openAndroidManifest(doc)) + if (forceUpdate && androidPath.toFileInfo().exists()) { + QDomElement ignoreFile = srcVersionDoc.documentElement().firstChildElement(QLatin1String("ignore")).firstChildElement(QLatin1String("file")); + while (!ignoreFile.isNull()) { + m_ignoreFiles << ignoreFile.text(); + ignoreFile = ignoreFile.nextSiblingElement(); + } + } + } + + if (!forceUpdate && androidPath.toFileInfo().exists() + && manifestPath(target).toFileInfo().exists() + && androidPath.append(QLatin1String("/src")).toFileInfo().exists() + && androidPath.append(QLatin1String("/res")).toFileInfo().exists()) + return true; + + forceUpdate &= androidPath.toFileInfo().exists(); + + if (!dirPath(target).toFileInfo().exists() && !projectDir.mkdir(AndroidDirName)) { + raiseError(tr("Error creating Android directory '%1'.").arg(AndroidDirName)); return false; - QDomElement manifestElem = doc.documentElement(); - manifestElem.setAttribute(QLatin1String("android:versionName"), version); - return saveAndroidManifest(doc); -} + } -QStringList AndroidTarget::permissions() const -{ - QStringList per; - QDomDocument doc; - if (!openAndroidManifest(doc)) - return per; - QDomElement permissionElem = doc.documentElement().firstChildElement(QLatin1String("uses-permission")); - while (!permissionElem.isNull()) { - per << permissionElem.attribute(QLatin1String("android:name")); - permissionElem = permissionElem.nextSiblingElement(QLatin1String("uses-permission")); + QStringList androidFiles; + QDirIterator it(javaSrcPath.toString(), QDirIterator::Subdirectories); + int pos = it.path().size(); + while (it.hasNext()) { + it.next(); + if (it.fileInfo().isDir()) { + projectDir.mkpath(AndroidDirName + it.filePath().mid(pos)); + } else { + const Utils::FileName dstFile = androidPath.append(it.filePath().mid(pos)); + if (m_ignoreFiles.contains(it.fileName())) { + continue; + } else { + if (dstFile.toFileInfo().exists()) + QFile::remove(dstFile.toString()); + else + androidFiles << dstFile.toString(); + } + QFile::copy(it.filePath(), dstFile.toString()); + } } - return per; -} + if (!androidFiles.isEmpty()) + qt4Project->rootProjectNode()->addFiles(ProjectExplorer::UnknownFileType, androidFiles); -bool AndroidTarget::setPermissions(const QStringList &permissions) const -{ - QDomDocument doc; - if (!openAndroidManifest(doc)) + QStringList sdks = AndroidConfigurations::instance().sdkTargets(); + if (sdks.isEmpty()) { + raiseError(tr("No Qt for Android SDKs were found.\nPlease install at least one SDK.")); return false; - QDomElement docElement = doc.documentElement(); - QDomElement permissionElem = docElement.firstChildElement(QLatin1String("uses-permission")); - while (!permissionElem.isNull()) { - docElement.removeChild(permissionElem); - permissionElem = docElement.firstChildElement(QLatin1String("uses-permission")); } + updateTarget(target, AndroidConfigurations::instance().sdkTargets().at(0)); + QStringList apps = availableTargetApplications(target); + if (!apps.isEmpty()) + setTargetApplication(target, apps.at(0)); - foreach (const QString &permission, permissions ) { - permissionElem = doc.createElement(QLatin1String("uses-permission")); - permissionElem.setAttribute(QLatin1String("android:name"), permission); - docElement.appendChild(permissionElem); + QString applicationName = target->project()->displayName(); + if (!applicationName.isEmpty()) { + setPackageName(target, packageName(target) + QLatin1Char('.') + applicationName); + applicationName[0] = applicationName[0].toUpper(); + setApplicationName(target, applicationName); } - return saveAndroidManifest(doc); -} + if (forceUpdate) + QMessageBox::warning(0, tr("Warning"), tr("Android files have been updated automatically")); + return true; +} -QStringList AndroidTarget::getDependencies(const QString &readelfPath, const QString &lib) const +void AndroidManager::updateTarget(ProjectExplorer::Target *target, const QString &targetSDK, const QString &name) { - QStringList libs; + QString androidDir = dirPath(target).toString(); - QProcess readelfProc; - readelfProc.start(readelfPath, QStringList() << QLatin1String("-d") << QLatin1String("-W") << lib); + // clean previous build + QProcess androidProc; + androidProc.setWorkingDirectory(androidDir); + androidProc.start(AndroidConfigurations::instance().antToolPath().toString(), + QStringList() << QLatin1String("clean")); + if (!androidProc.waitForFinished(-1)) + androidProc.terminate(); + // clean previous build - if (!readelfProc.waitForFinished(-1)) { - readelfProc.terminate(); - return libs; - } + int targetSDKNumber = targetSDK.mid(targetSDK.lastIndexOf(QLatin1Char('-')) + 1).toInt(); + bool commentLines = false; + QDirIterator it(androidDir, QStringList() << QLatin1String("*.java"), QDir::Files, QDirIterator::Subdirectories); + while (it.hasNext()) { + it.next(); + QFile file(it.filePath()); + if (!file.open(QIODevice::ReadWrite)) + continue; + QList<QByteArray> lines = file.readAll().trimmed().split('\n'); - QList<QByteArray> lines = readelfProc.readAll().trimmed().split('\n'); - foreach (const QByteArray &line, lines) { - if (line.contains("(NEEDED)") && line.contains("Shared library:") ) { - const int pos = line.lastIndexOf('[') + 1; - libs << QString::fromLatin1(line.mid(pos, line.lastIndexOf(']') - pos)); + bool modified = false; + bool comment = false; + for (int i = 0; i < lines.size(); i++) { + if (lines[i].contains("@ANDROID-")) { + commentLines = targetSDKNumber < lines[i].mid(lines[i].lastIndexOf('-') + 1).toInt(); + comment = !comment; + continue; + } + if (!comment) + continue; + if (commentLines) { + if (!lines[i].trimmed().startsWith("//QtCreator")) { + lines[i] = "//QtCreator " + lines[i]; + modified = true; + } + } else { if (lines[i].trimmed().startsWith("//QtCreator")) { + lines[i] = lines[i].mid(12); + modified = true; + } + } } + if (modified) { + file.resize(0); + foreach (const QByteArray &line, lines) { + file.write(line); + file.write("\n"); + } + } + file.close(); } - return libs; + + QStringList params; + params << QLatin1String("update") << QLatin1String("project") << QLatin1String("-p") << androidDir; + if (!targetSDK.isEmpty()) + params << QLatin1String("-t") << targetSDK; + if (!name.isEmpty()) + params << QLatin1String("-n") << name; + androidProc.start(AndroidConfigurations::instance().androidToolPath().toString(), params); + if (!androidProc.waitForFinished(-1)) + androidProc.terminate(); } -int AndroidTarget::setLibraryLevel(const QString &library, LibrariesMap &mapLibs) const +Utils::FileName AndroidManager::localLibsRulesFilePath(ProjectExplorer::Target *target) { - int maxlevel = mapLibs[library].level; - if (maxlevel > 0) - return maxlevel; - foreach (QString lib, mapLibs[library].dependencies) { - foreach (const QString &key, mapLibs.keys()) { - if (library == key) - continue; - if (key == lib) { - int libLevel = mapLibs[key].level; - - if (libLevel < 0) - libLevel = setLibraryLevel(key, mapLibs); + QtSupport::BaseQtVersion *version = QtSupport::QtProfileInformation::qtVersion(target->profile()); + if (!version) + return Utils::FileName(); + return Utils::FileName::fromString(version->versionInfo()[QLatin1String("QT_INSTALL_LIBS")] + QLatin1String("/rules.xml")); +} - if (libLevel > maxlevel) - maxlevel = libLevel; - break; - } - } - } - if (mapLibs[library].level < 0) - mapLibs[library].level = maxlevel + 1; - return maxlevel + 1; +QString AndroidManager::loadLocalLibs(ProjectExplorer::Target *target, int apiLevel) +{ + return loadLocal(target, apiLevel, Lib); } -bool AndroidTarget::qtLibrariesLessThan(const Library &a, const Library &b) +QString AndroidManager::loadLocalJars(ProjectExplorer::Target *target, int apiLevel) { - if (a.level == b.level) - return a.name < b.name; - return a.level < b.level; + return loadLocal(target, apiLevel, Jar); } -QStringList AndroidTarget::availableQtLibs() const +QStringList AndroidManager::availableQtLibs(ProjectExplorer::Target *target) { - const QString readelfPath = AndroidConfigurations::instance().readelfPath(activeRunConfiguration()->abi().architecture()); + QtSupport::BaseQtVersion *version = QtSupport::QtProfileInformation::qtVersion(target->profile()); + if (!target->activeRunConfiguration()) + return QStringList(); + + Utils::FileName readelfPath = AndroidConfigurations::instance().readelfPath(target->activeRunConfiguration()->abi().architecture()); QStringList libs; - const Qt4Project *const qt4Project = qobject_cast<const Qt4Project *>(project()); - if (!qt4Project || !qt4Project->activeTarget()->activeQt4BuildConfiguration()->qtVersion()) + const Qt4ProjectManager::Qt4Project *const qt4Project + = qobject_cast<const Qt4ProjectManager::Qt4Project *>(target->project()); + if (!qt4Project || !version) return libs; - QString qtLibsPath = qt4Project->activeTarget()->activeQt4BuildConfiguration()->qtVersion()->versionInfo()[QLatin1String("QT_INSTALL_LIBS")]; - if (!QFile::exists(readelfPath)) { + QString qtLibsPath = version->versionInfo()[QLatin1String("QT_INSTALL_LIBS")]; + if (!readelfPath.toFileInfo().exists()) { QDirIterator libsIt(qtLibsPath, QStringList() << QLatin1String("libQt*.so")); while (libsIt.hasNext()) { libsIt.next(); @@ -787,7 +602,7 @@ QStringList AndroidTarget::availableQtLibs() const while (it.hasNext()) { libPath = it.next(); const QString library = libPath.absolutePath().mid(libPath.absolutePath().lastIndexOf(QLatin1Char('/')) + 1); - mapLibs[library].dependencies = getDependencies(readelfPath, libPath.absolutePath()); + mapLibs[library].dependencies = dependencies(readelfPath, libPath.absolutePath()); } // clean dependencies @@ -828,40 +643,169 @@ QStringList AndroidTarget::availableQtLibs() const return libs; } -QIcon AndroidTarget::androidIcon(AndroidIconType type) const +QStringList AndroidManager::qtLibs(ProjectExplorer::Target *target) { - switch (type) { - case HighDPI: - return QIcon(androidDirPath() + QLatin1String("/res/drawable-hdpi/icon.png")); - case MediumDPI: - return QIcon(androidDirPath() + QLatin1String("/res/drawable-mdpi/icon.png")); - case LowDPI: - return QIcon(androidDirPath() + QLatin1String("/res/drawable-ldpi/icon.png")); + return libsXml(target, QLatin1String("qt_libs")); +} + +bool AndroidManager::setQtLibs(ProjectExplorer::Target *target, const QStringList &libs) +{ + return setLibsXml(target, libs, QLatin1String("qt_libs")); +} + +QStringList AndroidManager::availablePrebundledLibs(ProjectExplorer::Target *target) +{ + QStringList libs; + Qt4ProjectManager::Qt4Project *qt4Project = qobject_cast<Qt4ProjectManager::Qt4Project *>(target->project()); + if (!qt4Project) + return libs; + + foreach (Qt4ProjectManager::Qt4ProFileNode *node, qt4Project->allProFiles()) + if (node->projectType() == Qt4ProjectManager::LibraryTemplate) + libs << QLatin1String("lib") + node->targetInformation().target + QLatin1String(".so"); + return libs; +} + +QStringList AndroidManager::prebundledLibs(ProjectExplorer::Target *target) +{ + return libsXml(target, QLatin1String("bundled_libs")); +} + +bool AndroidManager::setPrebundledLibs(ProjectExplorer::Target *target, const QStringList &libs) +{ + return setLibsXml(target, libs, QLatin1String("bundled_libs")); +} + +bool AndroidManager::openLibsXml(ProjectExplorer::Target *target, QDomDocument &doc) +{ + return openXmlFile(target, doc, libsPath(target)); +} + +bool AndroidManager::saveLibsXml(ProjectExplorer::Target *target, QDomDocument &doc) +{ + return saveXmlFile(target, doc, libsPath(target)); +} + +AndroidManager::AndroidManager(QObject *parent) : + QObject(parent) +{ + m_instance = this; + +// ProjectExplorer::SessionManager *sm = ProjectExplorerPlugin::instance()->session(); +// connect(sm, SIGNAL(projectAdded(ProjectExplorer::Project*)), +// this, SLOT(handleProjectAdditions(ProjectExplorer::Project*))); +} + +void AndroidManager::raiseError(const QString &reason) +{ + QMessageBox::critical(0, tr("Error creating Android templates"), reason); +} + +QString AndroidManager::loadLocal(ProjectExplorer::Target *target, int apiLevel, ItemType item) +{ + QString itemType; + if (item == Lib) + itemType = QLatin1String("lib"); + else + itemType = QLatin1String("jar"); + + QString localLibs; + + QDomDocument doc; + if (!openXmlFile(target, doc, localLibsRulesFilePath(target))) + return localLibs; + + QStringList libs; + libs << qtLibs(target) << prebundledLibs(target); + QDomElement element = doc.documentElement().firstChildElement(QLatin1String("platforms")).firstChildElement(itemType + QLatin1Char('s')).firstChildElement(QLatin1String("version")); + while (!element.isNull()) { + if (element.attribute(QLatin1String("value")).toInt() == apiLevel) { + if (element.hasAttribute(QLatin1String("symlink"))) + apiLevel = element.attribute(QLatin1String("symlink")).toInt(); + break; + } + element = element.nextSiblingElement(QLatin1String("version")); } - return QIcon(); + + element = doc.documentElement().firstChildElement(QLatin1String("dependencies")).firstChildElement(QLatin1String("lib")); + while (!element.isNull()) { + if (libs.contains(element.attribute(QLatin1String("name")))) { + QDomElement libElement = element.firstChildElement(QLatin1String("depends")).firstChildElement(itemType); + while (!libElement.isNull()) { + localLibs += libElement.attribute(QLatin1String("file")).arg(apiLevel) + QLatin1Char(':'); + libElement = libElement.nextSiblingElement(itemType); + } + + libElement = element.firstChildElement(QLatin1String("replaces")).firstChildElement(itemType); + while (!libElement.isNull()) { + localLibs.replace(libElement.attribute(QLatin1String("file")).arg(apiLevel) + QLatin1Char(':'), QString()); + libElement = libElement.nextSiblingElement(itemType); + } + } + element = element.nextSiblingElement(QLatin1String("lib")); + } + return localLibs; +} + +bool AndroidManager::openXmlFile(ProjectExplorer::Target *target, QDomDocument &doc, + const Utils::FileName &fileName, bool createAndroidTemplates) +{ + if (createAndroidTemplates && !createAndroidTemplatesIfNecessary(target)) + return false; + + QFile f(fileName.toString()); + if (!f.open(QIODevice::ReadOnly)) + return false; + + if (!doc.setContent(f.readAll())) { + raiseError(tr("Can't parse '%1'").arg(fileName.toUserOutput())); + return false; + } + return true; } -bool AndroidTarget::setAndroidIcon(AndroidIconType type, const QString &iconFileName) const +bool AndroidManager::saveXmlFile(ProjectExplorer::Target *target, QDomDocument &doc, const Utils::FileName &fileName) +{ + if (!createAndroidTemplatesIfNecessary(target)) + return false; + + QFile f(fileName.toString()); + if (!f.open(QIODevice::WriteOnly)) { + raiseError(tr("Can't open '%1'").arg(fileName.toUserOutput())); + return false; + } + return f.write(doc.toByteArray(4)) >= 0; +} + +bool AndroidManager::openManifest(ProjectExplorer::Target *target, QDomDocument &doc) +{ + return openXmlFile(target, doc, manifestPath(target)); +} + +bool AndroidManager::saveManifest(ProjectExplorer::Target *target, QDomDocument &doc) +{ + return saveXmlFile(target, doc, manifestPath(target)); +} + +QString AndroidManager::iconPath(ProjectExplorer::Target *target, AndroidManager::IconType type) { switch (type) { case HighDPI: - QFile::remove(androidDirPath() + QLatin1String("/res/drawable-hdpi/icon.png")); - return QFile::copy(iconFileName, androidDirPath() + QLatin1String("/res/drawable-hdpi/icon.png")); + return dirPath(target).appendPath(QLatin1String("res/drawable-hdpi/icon.png")).toString(); case MediumDPI: - QFile::remove(androidDirPath() + QLatin1String("/res/drawable-mdpi/icon.png")); - return QFile::copy(iconFileName, androidDirPath() + QLatin1String("/res/drawable-mdpi/icon.png")); + return dirPath(target).appendPath(QLatin1String("res/drawable-mdpi/icon.png")).toString(); case LowDPI: - QFile::remove(androidDirPath() + QLatin1String("/res/drawable-ldpi/icon.png")); - return QFile::copy(iconFileName, androidDirPath() + QLatin1String("/res/drawable-ldpi/icon.png")); + return dirPath(target).appendPath(QLatin1String("res/drawable-ldpi/icon.png")).toString(); + default: + return QString(); } - return false; } -QStringList AndroidTarget::libsXml(const QString &tag) const +QStringList AndroidManager::libsXml(ProjectExplorer::Target *target, const QString &tag) { QStringList libs; QDomDocument doc; - if (!openLibsXml(doc)) + if (!openLibsXml(target, doc)) return libs; QDomElement arrayElem = doc.documentElement().firstChildElement(QLatin1String("array")); while (!arrayElem.isNull()) { @@ -878,10 +822,10 @@ QStringList AndroidTarget::libsXml(const QString &tag) const return libs; } -bool AndroidTarget::setLibsXml(const QStringList &libs, const QString &tag) const +bool AndroidManager::setLibsXml(ProjectExplorer::Target *target, const QStringList &libs, const QString &tag) { QDomDocument doc; - if (!openLibsXml(doc)) + if (!openLibsXml(target, doc)) return false; QDomElement arrayElem = doc.documentElement().firstChildElement(QLatin1String("array")); while (!arrayElem.isNull()) { @@ -895,105 +839,83 @@ bool AndroidTarget::setLibsXml(const QStringList &libs, const QString &tag) cons arrayElem.appendChild(item); } doc.documentElement().appendChild(arrayElem); - return saveLibsXml(doc); + return saveLibsXml(target, doc); } arrayElem = arrayElem.nextSiblingElement(QLatin1String("array")); } return false; } -QStringList AndroidTarget::qtLibs() const -{ - return libsXml(QLatin1String("qt_libs")); -} - -bool AndroidTarget::setQtLibs(const QStringList &libs) const -{ - return setLibsXml(libs, QLatin1String("qt_libs")); -} - -QStringList AndroidTarget::availablePrebundledLibs() const -{ - QStringList libs; - Qt4Project *qt4Project = qobject_cast<Qt4Project *>(project()); - QList<Qt4Project *> qt4Projects; - qt4Projects << qt4Project; - foreach (Qt4Project *qt4Project, qt4Projects) - foreach (Qt4ProFileNode *node, qt4Project->allProFiles()) - if (node->projectType() == LibraryTemplate) - libs << QLatin1String("lib") + node->targetInformation().target + QLatin1String(".so"); - - return libs; -} - -QStringList AndroidTarget::prebundledLibs() const +QIcon AndroidManager::icon(ProjectExplorer::Target *target, IconType type) { - return libsXml(QLatin1String("bundled_libs")); + return QIcon(iconPath(target, type)); } -bool AndroidTarget::setPrebundledLibs(const QStringList &libs) const +bool AndroidManager::setIcon(ProjectExplorer::Target *target, IconType type, const QString &iconFileName) { + if (!QFileInfo(iconFileName).exists()) + return false; - return setLibsXml(libs, QLatin1String("bundled_libs")); + const QString path = iconPath(target, type); + QFile::remove(path); + return QFile::copy(iconFileName, path); } -QIcon AndroidTarget::highDpiIcon() const +QStringList AndroidManager::dependencies(const Utils::FileName &readelfPath, const QString &lib) { - return androidIcon(HighDPI); -} + QStringList libs; -bool AndroidTarget::setHighDpiIcon(const QString &iconFilePath) const -{ - return setAndroidIcon(HighDPI, iconFilePath); -} + QProcess readelfProc; + readelfProc.start(readelfPath.toString(), QStringList() << QLatin1String("-d") << QLatin1String("-W") << lib); -QIcon AndroidTarget::mediumDpiIcon() const -{ - return androidIcon(MediumDPI); -} + if (!readelfProc.waitForFinished(-1)) { + readelfProc.terminate(); + return libs; + } -bool AndroidTarget::setMediumDpiIcon(const QString &iconFilePath) const -{ - return setAndroidIcon(MediumDPI, iconFilePath); + QList<QByteArray> lines = readelfProc.readAll().trimmed().split('\n'); + foreach (const QByteArray &line, lines) { + if (line.contains("(NEEDED)") && line.contains("Shared library:") ) { + const int pos = line.lastIndexOf('[') + 1; + libs << QString::fromLatin1(line.mid(pos, line.lastIndexOf(']') - pos)); + } + } + return libs; } -QIcon AndroidTarget::lowDpiIcon() const +int AndroidManager::setLibraryLevel(const QString &library, LibrariesMap &mapLibs) { - return androidIcon(LowDPI); -} + int maxlevel = mapLibs[library].level; + if (maxlevel > 0) + return maxlevel; + foreach (QString lib, mapLibs[library].dependencies) { + foreach (const QString &key, mapLibs.keys()) { + if (library == key) + continue; + if (key == lib) { + int libLevel = mapLibs[key].level; -bool AndroidTarget::setLowDpiIcon(const QString &iconFilePath) const -{ - return setAndroidIcon(LowDPI, iconFilePath); -} + if (libLevel < 0) + libLevel = setLibraryLevel(key, mapLibs); -QString AndroidTarget::targetSDK() const -{ - if (!createAndroidTemplatesIfNecessary()) - return AndroidConfigurations::instance().bestMatch(QLatin1String("android-8")); - QFile file(androidDefaultPropertiesPath()); - if (!file.open(QIODevice::ReadOnly)) - return AndroidConfigurations::instance().bestMatch(QLatin1String("android-8")); - while (!file.atEnd()) { - QByteArray line = file.readLine(); - if (line.startsWith("target=")) - return QString::fromLatin1(line.trimmed().mid(7)); + if (libLevel > maxlevel) + maxlevel = libLevel; + break; + } + } } - return AndroidConfigurations::instance().bestMatch(QLatin1String("android-8")); -} - -bool AndroidTarget::setTargetSDK(const QString &target) const -{ - updateProject(target, applicationName()); - return true; + if (mapLibs[library].level < 0) + mapLibs[library].level = maxlevel + 1; + return maxlevel + 1; } -void AndroidTarget::raiseError(const QString &reason) const +bool AndroidManager::qtLibrariesLessThan(const Library &a, const Library &b) { - QMessageBox::critical(0, tr("Error creating Android templates"), reason); + if (a.level == b.level) + return a.name < b.name; + return a.level < b.level; } - } // namespace Internal } // namespace Qt4ProjectManager diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h new file mode 100644 index 00000000000..6c99b325639 --- /dev/null +++ b/src/plugins/android/androidmanager.h @@ -0,0 +1,177 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 BogDan Vatra <[email protected]> +** +** Contact: Nokia Corporation ([email protected]) +** +** +** GNU Lesser General Public License Usage +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at [email protected]. +** +**************************************************************************/ + +#ifndef ANDROIDMANAGER_H +#define ANDROIDMANAGER_H + +#include <utils/fileutils.h> + +#include <QDomDocument> +#include <QObject> +#include <QStringList> + +namespace ProjectExplorer { class Target; } + +namespace Android { +class AndroidPlugin; + +namespace Internal { + +class AndroidManager : public QObject +{ + Q_OBJECT + +public: + enum BuildType + { + DebugBuild, + ReleaseBuildUnsigned, + ReleaseBuildSigned + }; + + static AndroidManager *instance(); + + ~AndroidManager(); + + static bool supportsAndroid(ProjectExplorer::Target *target); + + static QString packageName(ProjectExplorer::Target *target); + static bool setPackageName(ProjectExplorer::Target *target, const QString &name); + + static QString applicationName(ProjectExplorer::Target *target); + static bool setApplicationName(ProjectExplorer::Target *target, const QString &name); + + static QStringList permissions(ProjectExplorer::Target *target); + static bool setPermissions(ProjectExplorer::Target *target, const QStringList &permissions); + + static QString intentName(ProjectExplorer::Target *target); + static QString activityName(ProjectExplorer::Target *target); + + static int versionCode(ProjectExplorer::Target *target); + static bool setVersionCode(ProjectExplorer::Target *target, int version); + static QString versionName(ProjectExplorer::Target *target); + static bool setVersionName(ProjectExplorer::Target *target, const QString &version); + + static QIcon highDpiIcon(ProjectExplorer::Target *target); + static bool setHighDpiIcon(ProjectExplorer::Target *target, const QString &iconFilePath); + static QIcon mediumDpiIcon(ProjectExplorer::Target *target); + static bool setMediumDpiIcon(ProjectExplorer::Target *target, const QString &iconFilePath); + static QIcon lowDpiIcon(ProjectExplorer::Target *target); + static bool setLowDpiIcon(ProjectExplorer::Target *target, const QString &iconFilePath); + + static QStringList availableTargetApplications(ProjectExplorer::Target *target); + static QString targetApplication(ProjectExplorer::Target *target); + static bool setTargetApplication(ProjectExplorer::Target *target, const QString &name); + static QString targetApplicationPath(ProjectExplorer::Target *target); + + static QString targetSDK(ProjectExplorer::Target *target); + static bool setTargetSDK(ProjectExplorer::Target *target, const QString &sdk); + + static Utils::FileName dirPath(ProjectExplorer::Target *target); + static Utils::FileName manifestPath(ProjectExplorer::Target *target); + static Utils::FileName libsPath(ProjectExplorer::Target *target); + static Utils::FileName stringsPath(ProjectExplorer::Target *target); + static Utils::FileName defaultPropertiesPath(ProjectExplorer::Target *target); + static Utils::FileName srcPath(ProjectExplorer::Target *target); + static Utils::FileName apkPath(ProjectExplorer::Target *target, BuildType buildType); + + static bool createAndroidTemplatesIfNecessary(ProjectExplorer::Target *target); + static void updateTarget(ProjectExplorer::Target *target, const QString &targetSDK, + const QString &name = QString()); + + static Utils::FileName localLibsRulesFilePath(ProjectExplorer::Target *target); + static QString loadLocalLibs(ProjectExplorer::Target *target, int apiLevel); + static QString loadLocalJars(ProjectExplorer::Target *target, int apiLevel); + + static QStringList availableQtLibs(ProjectExplorer::Target *target); + static QStringList qtLibs(ProjectExplorer::Target *target); + static bool setQtLibs(ProjectExplorer::Target *target, const QStringList &libs); + + static QStringList availablePrebundledLibs(ProjectExplorer::Target *target); + static QStringList prebundledLibs(ProjectExplorer::Target *target); + static bool setPrebundledLibs(ProjectExplorer::Target *target, const QStringList &libs); + +private: + explicit AndroidManager(QObject *parent = 0); + + static void raiseError(const QString &reason); + static bool openXmlFile(ProjectExplorer::Target *target, QDomDocument &doc, + const Utils::FileName &fileName, bool createAndroidTemplates = false); + static bool saveXmlFile(ProjectExplorer::Target *target, QDomDocument &doc, const Utils::FileName &fileName); + static bool openManifest(ProjectExplorer::Target *target, QDomDocument &doc); + static bool saveManifest(ProjectExplorer::Target *target, QDomDocument &doc); + static bool openLibsXml(ProjectExplorer::Target *target, QDomDocument &doc); + static bool saveLibsXml(ProjectExplorer::Target *target, QDomDocument &doc); + static QStringList libsXml(ProjectExplorer::Target *target, const QString &tag); + static bool setLibsXml(ProjectExplorer::Target *target, const QStringList &libs, const QString &tag); + + enum ItemType + { + Lib, + Jar + }; + static QString loadLocal(ProjectExplorer::Target *target, int apiLevel, ItemType item); + + class Library + { + public: + Library() + { level = -1; } + int level; + QStringList dependencies; + QString name; + }; + typedef QMap<QString, Library> LibrariesMap; + + enum IconType + { + HighDPI, + MediumDPI, + LowDPI + }; + static QString iconPath(ProjectExplorer::Target *target, IconType type); + static QIcon icon(ProjectExplorer::Target *target, IconType type); + static bool setIcon(ProjectExplorer::Target *target, IconType type, const QString &iconFileName); + + static QStringList dependencies(const Utils::FileName &readelfPath, const QString &lib); + static int setLibraryLevel(const QString &library, LibrariesMap &mapLibs); + static bool qtLibrariesLessThan(const Library &a, const Library &b); + + static AndroidManager *m_instance; + + friend class Android::AndroidPlugin; +}; + +} // namespace Internal +} // namespace Android + +#endif // ANDROIDMANAGER_H diff --git a/src/plugins/android/androidpackagecreationfactory.cpp b/src/plugins/android/androidpackagecreationfactory.cpp index 7b3429cf721..019b2582435 100644 --- a/src/plugins/android/androidpackagecreationfactory.cpp +++ b/src/plugins/android/androidpackagecreationfactory.cpp @@ -33,11 +33,14 @@ #include "androidpackagecreationfactory.h" #include "androidpackagecreationstep.h" +#include "androidmanager.h" #include <projectexplorer/buildsteplist.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/target.h> #include <qt4projectmanager/qt4projectmanagerconstants.h> +#include <qtsupport/qtprofileinformation.h> +#include <qtsupport/qtsupportconstants.h> #include <QCoreApplication> @@ -54,11 +57,13 @@ AndroidPackageCreationFactory::AndroidPackageCreationFactory(QObject *parent) QList<Core::Id> AndroidPackageCreationFactory::availableCreationIds(ProjectExplorer::BuildStepList *parent) const { - if (parent->id() == Core::Id(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY) - && parent->target()->id() == Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID) - && !parent->contains(AndroidPackageCreationStep::CreatePackageId)) - return QList<Core::Id>() << AndroidPackageCreationStep::CreatePackageId; - return QList<Core::Id>(); + if (parent->id() != Core::Id(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY)) + return QList<Core::Id>(); + if (!AndroidManager::supportsAndroid(parent->target())) + return QList<Core::Id>(); + if (parent->contains(AndroidPackageCreationStep::CreatePackageId)) + return QList<Core::Id>(); + return QList<Core::Id>() << AndroidPackageCreationStep::CreatePackageId; } QString AndroidPackageCreationFactory::displayNameForId(const Core::Id id) const @@ -71,10 +76,7 @@ QString AndroidPackageCreationFactory::displayNameForId(const Core::Id id) const bool AndroidPackageCreationFactory::canCreate(ProjectExplorer::BuildStepList *parent, const Core::Id id) const { - return parent->id() == Core::Id(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY) - && id == Core::Id(AndroidPackageCreationStep::CreatePackageId) - && parent->target()->id() == Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID) - && !parent->contains(AndroidPackageCreationStep::CreatePackageId); + return availableCreationIds(parent).contains(id); } BuildStep *AndroidPackageCreationFactory::create(ProjectExplorer::BuildStepList *parent, const Core::Id id) diff --git a/src/plugins/android/androidpackagecreationstep.cpp b/src/plugins/android/androidpackagecreationstep.cpp index f42a4e834ff..dccfe9423bb 100644 --- a/src/plugins/android/androidpackagecreationstep.cpp +++ b/src/plugins/android/androidpackagecreationstep.cpp @@ -36,15 +36,15 @@ #include "androiddeploystep.h" #include "androidglobal.h" #include "androidpackagecreationwidget.h" -#include "androidtarget.h" +#include "androidmanager.h" #include <projectexplorer/buildsteplist.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/runconfiguration.h> +#include <projectexplorer/target.h> #include <qt4projectmanager/qt4buildconfiguration.h> #include <qt4projectmanager/qt4project.h> #include <qt4projectmanager/qt4nodes.h> -#include <qt4projectmanager/qt4target.h> #include <coreplugin/icore.h> #include <coreplugin/fileutils.h> @@ -142,35 +142,35 @@ void AndroidPackageCreationStep::ctor() bool AndroidPackageCreationStep::init() { - AndroidTarget *target = androidTarget(); - const Qt4BuildConfiguration *bc = target->activeQt4BuildConfiguration(); - if (!target) { - raiseError(tr("Cannot create android package: current target is not android.")); + const Qt4BuildConfiguration *bc = qobject_cast<Qt4BuildConfiguration *>(target()->activeBuildConfiguration()); + if (!bc) { + raiseError(tr("Cannot create android package: current build configuration is not Qt4.")); return false; } - m_outputParser.setProjectFileList(target->qt4Project()->files(Project::AllFiles)); + Qt4Project *project = static_cast<Qt4Project *>(target()->project()); + m_outputParser.setProjectFileList(project->files(Project::AllFiles)); // Copying - m_androidDir = target->androidDirPath(); - QString androidLibPath; - if (target->qt4Project()->rootQt4ProjectNode()->variableValue(Qt4ProjectManager::ConfigVar).contains(QLatin1String("x86"))) - androidLibPath = m_androidDir + QLatin1String("/libs/x86"); - else if (target->qt4Project()->rootQt4ProjectNode() + m_androidDir = AndroidManager::dirPath(target()); + Utils::FileName androidLibPath; + if (project->rootQt4ProjectNode()->variableValue(Qt4ProjectManager::ConfigVar).contains(QLatin1String("x86"))) + androidLibPath = m_androidDir.appendPath(QLatin1String("libs/x86")); + else if (project->rootQt4ProjectNode() ->variableValue(Qt4ProjectManager::ConfigVar).contains(QLatin1String("armeabi-v7a"))) - androidLibPath = m_androidDir + QLatin1String("/libs/armeabi-v7a"); + androidLibPath = m_androidDir.appendPath(QLatin1String("libs/armeabi-v7a")); else - androidLibPath = m_androidDir + QLatin1String("/libs/armeabi"); - m_gdbServerDestination = androidLibPath + QLatin1String("/gdbserver"); - m_gdbServerSource = AndroidConfigurations::instance().gdbServerPath(target->activeRunConfiguration()->abi().architecture()); + androidLibPath = m_androidDir.appendPath(QLatin1String("libs/armeabi")); + m_gdbServerDestination = androidLibPath.appendPath(QLatin1String("gdbserver")); + m_gdbServerSource = AndroidConfigurations::instance().gdbServerPath(target()->activeRunConfiguration()->abi().architecture()); m_debugBuild = bc->qmakeBuildConfiguration() & QtSupport::BaseQtVersion::DebugBuild; - if (!target->createAndroidTemplatesIfNecessary()) + if (!AndroidManager::createAndroidTemplatesIfNecessary(target())) return false; - target->updateProject(target->targetSDK(), target->applicationName()); + AndroidManager::updateTarget(target(), AndroidManager::targetSDK(target()), AndroidManager::applicationName(target())); m_antToolPath = AndroidConfigurations::instance().antToolPath(); - m_apkPathUnsigned = target->apkPath(AndroidTarget::ReleaseBuildUnsigned); - m_apkPathSigned = target->apkPath(AndroidTarget::ReleaseBuildSigned); + m_apkPathUnsigned = AndroidManager::apkPath(target(), AndroidManager::ReleaseBuildUnsigned); + m_apkPathSigned = AndroidManager::apkPath(target(), AndroidManager::ReleaseBuildSigned); m_keystorePathForRun = m_keystorePath; m_certificatePasswdForRun = m_certificatePasswd; m_jarSigner = AndroidConfigurations::instance().jarsignerPath(); @@ -188,15 +188,10 @@ BuildStepConfigWidget *AndroidPackageCreationStep::createConfigWidget() return new AndroidPackageCreationWidget(this); } -AndroidTarget *AndroidPackageCreationStep::androidTarget() const -{ - return qobject_cast<AndroidTarget *>(target()); -} - void AndroidPackageCreationStep::checkRequiredLibraries() { QProcess readelfProc; - QString appPath = androidTarget()->targetApplicationPath(); + QString appPath = AndroidManager::targetApplicationPath(target()); if (!QFile::exists(appPath)) { raiseError(tr("Cannot find read elf information"), tr("Cannot find '%1'.\n" @@ -204,7 +199,7 @@ void AndroidPackageCreationStep::checkRequiredLibraries() "built successfully and is selected in Application tab ('Run option') ").arg(appPath)); return; } - readelfProc.start(AndroidConfigurations::instance().readelfPath(androidTarget()->activeRunConfiguration()->abi().architecture()), + readelfProc.start(AndroidConfigurations::instance().readelfPath(target()->activeRunConfiguration()->abi().architecture()).toString(), QStringList() << QLatin1String("-d") << QLatin1String("-W") << appPath); if (!readelfProc.waitForFinished(-1)) { readelfProc.terminate(); @@ -218,44 +213,44 @@ void AndroidPackageCreationStep::checkRequiredLibraries() libs << QString::fromLatin1(line.mid(pos, line.length() - pos - 1)); } } - QStringList checkedLibs = androidTarget()->qtLibs(); + QStringList checkedLibs = AndroidManager::qtLibs(target()); QStringList requiredLibraries; - foreach (const QString &qtLib, androidTarget()->availableQtLibs()) { + foreach (const QString &qtLib, AndroidManager::availableQtLibs(target())) { if (libs.contains(QLatin1String("lib") + qtLib + QLatin1String(".so")) || checkedLibs.contains(qtLib)) requiredLibraries << qtLib; } - androidTarget()->setQtLibs(requiredLibraries); + AndroidManager::setQtLibs(target(), requiredLibraries); - checkedLibs = androidTarget()->prebundledLibs(); + checkedLibs = AndroidManager::prebundledLibs(target()); requiredLibraries.clear(); - foreach (const QString &qtLib, androidTarget()->availableQtLibs()) { + foreach (const QString &qtLib, AndroidManager::availableQtLibs(target())) { if (libs.contains(qtLib) || checkedLibs.contains(qtLib)) requiredLibraries << qtLib; } - androidTarget()->setPrebundledLibs(requiredLibraries); + AndroidManager::setPrebundledLibs(target(), requiredLibraries); emit updateRequiredLibrariesModels(); } void AndroidPackageCreationStep::initCheckRequiredLibrariesForRun() { - m_appPath = androidTarget()->targetApplicationPath(); - m_readElf = AndroidConfigurations::instance().readelfPath(androidTarget()->activeRunConfiguration()->abi().architecture()); - m_qtLibs = androidTarget()->qtLibs(); - m_availableQtLibs = androidTarget()->availableQtLibs(); - m_prebundledLibs = androidTarget()->prebundledLibs(); + m_appPath = Utils::FileName::fromString(AndroidManager::targetApplicationPath(target())); + m_readElf = AndroidConfigurations::instance().readelfPath(target()->activeRunConfiguration()->abi().architecture()); + m_qtLibs = AndroidManager::qtLibs(target()); + m_availableQtLibs = AndroidManager::availableQtLibs(target()); + m_prebundledLibs = AndroidManager::prebundledLibs(target()); } void AndroidPackageCreationStep::checkRequiredLibrariesForRun() { QProcess readelfProc; - if (!QFile::exists(m_appPath)) { - raiseError(tr("Cannot find read elf information"), + if (!m_appPath.toFileInfo().exists()) { + raiseError(tr("Can't find read elf information"), tr("Can't find '%1'.\n" "Please make sure your application is " - "built successfully and is selected in Application tab ('Run option') ").arg(m_appPath)); + "built successfully and is selected in Application tab ('Run option') ").arg(m_appPath.toUserOutput())); return; } - readelfProc.start(m_readElf, QStringList() << QLatin1String("-d") << QLatin1String("-W") << m_appPath); + readelfProc.start(m_readElf.toString(), QStringList() << QLatin1String("-d") << QLatin1String("-W") << m_appPath.toUserOutput()); if (!readelfProc.waitForFinished(-1)) { readelfProc.terminate(); return; @@ -290,20 +285,20 @@ void AndroidPackageCreationStep::checkRequiredLibrariesForRun() void AndroidPackageCreationStep::setQtLibs(const QStringList &qtLibs) { - androidTarget()->setQtLibs(qtLibs); + AndroidManager::setQtLibs(target(), qtLibs); } void AndroidPackageCreationStep::setPrebundledLibs(const QStringList &prebundledLibs) { - androidTarget()->setPrebundledLibs(prebundledLibs); + AndroidManager::setPrebundledLibs(target(), prebundledLibs); } -QString AndroidPackageCreationStep::keystorePath() +Utils::FileName AndroidPackageCreationStep::keystorePath() { return m_keystorePath; } -void AndroidPackageCreationStep::setKeystorePath(const QString &path) +void AndroidPackageCreationStep::setKeystorePath(const Utils::FileName &path) { m_keystorePath = path; m_certificatePasswd.clear(); @@ -336,13 +331,13 @@ QAbstractItemModel *AndroidPackageCreationStep::keystoreCertificates() QProcess keytoolProc; while (!rawCerts.length() || !m_keystorePasswd.length()) { QStringList params; - params << QLatin1String("-list") << QLatin1String("-v") << QLatin1String("-keystore") << m_keystorePathForRun << QLatin1String("-storepass"); + params << QLatin1String("-list") << QLatin1String("-v") << QLatin1String("-keystore") << m_keystorePathForRun.toUserOutput() << QLatin1String("-storepass"); if (!m_keystorePasswd.length()) keystorePassword(); if (!m_keystorePasswd.length()) return 0; params << m_keystorePasswd; - keytoolProc.start(AndroidConfigurations::instance().keytoolPath(), params); + keytoolProc.start(AndroidConfigurations::instance().keytoolPath().toString(), params); if (!keytoolProc.waitForStarted() || !keytoolProc.waitForFinished()) { QMessageBox::critical(0, tr("Error"), tr("Failed to run keytool")); @@ -363,14 +358,14 @@ bool AndroidPackageCreationStep::fromMap(const QVariantMap &map) { if (!BuildStep::fromMap(map)) return false; - m_keystorePath = map.value(KeystoreLocationKey).toString(); + m_keystorePath = Utils::FileName::fromString(map.value(KeystoreLocationKey).toString()); return true; } QVariantMap AndroidPackageCreationStep::toMap() const { QVariantMap map(BuildStep::toMap()); - map.insert(KeystoreLocationKey, m_keystorePath); + map.insert(KeystoreLocationKey, m_keystorePath.toString()); return map; } @@ -382,12 +377,12 @@ bool AndroidPackageCreationStep::createPackage() QStringList build; build << QLatin1String("clean"); - QFile::remove(m_gdbServerDestination); + QFile::remove(m_gdbServerDestination.toString()); if (m_debugBuild || !m_certificateAlias.length()) { build << QLatin1String("debug"); - if (!QFile::copy(m_gdbServerSource, m_gdbServerDestination)) { - raiseError(tr("Cannot copy gdbserver from '%1' to '%2'").arg(m_gdbServerSource) - .arg(m_gdbServerDestination)); + if (!QFile::copy(m_gdbServerSource.toString(), m_gdbServerDestination.toString())) { + raiseError(tr("Can't copy gdbserver from '%1' to '%2'").arg(m_gdbServerSource.toUserOutput()) + .arg(m_gdbServerDestination.toUserOutput())); return false; } } else { @@ -403,9 +398,9 @@ bool AndroidPackageCreationStep::createPackage() connect(buildProc, SIGNAL(readyReadStandardError()), this, SLOT(handleBuildStdErrOutput())); - buildProc->setWorkingDirectory(m_androidDir); + buildProc->setWorkingDirectory(m_androidDir.toString()); - if (!runCommand(buildProc, m_antToolPath, build)) { + if (!runCommand(buildProc, m_antToolPath.toString(), build)) { disconnect(buildProc, 0, this, 0); buildProc->deleteLater(); return false; @@ -425,11 +420,11 @@ bool AndroidPackageCreationStep::createPackage() QByteArray keyPass = m_certificatePasswdForRun.toUtf8(); build.clear(); - build << QLatin1String("-verbose") << QLatin1String("-keystore") << m_keystorePathForRun + build << QLatin1String("-verbose") << QLatin1String("-keystore") << m_keystorePathForRun.toUserOutput() << QLatin1String("-storepass") << m_keystorePasswd - << m_apkPathUnsigned + << m_apkPathUnsigned.toUserOutput() << m_certificateAlias; - buildProc->start(m_jarSigner, build); //TODO + buildProc->start(m_jarSigner.toString(), build); //TODO if (!buildProc->waitForStarted()) { disconnect(buildProc, 0, this, 0); buildProc->deleteLater(); @@ -446,9 +441,9 @@ bool AndroidPackageCreationStep::createPackage() emit addOutput(tr("Failed, try again"), ErrorMessageOutput); m_certificatePasswdForRun.clear(); } - if (QFile::rename(m_apkPathUnsigned, m_apkPathSigned)) { + if (QFile::rename(m_apkPathUnsigned.toString(), m_apkPathSigned.toString())) { emit addOutput(tr("Release signed package created to %1") - .arg(m_apkPathSigned) + .arg(m_apkPathSigned.toUserOutput()) , MessageOutput); if (m_openPackageLocation) @@ -465,7 +460,8 @@ void AndroidPackageCreationStep::stripAndroidLibs(const QStringList & files, Abi { QProcess stripProcess; foreach (const QString &file, files) { - stripProcess.start(AndroidConfigurations::instance().stripPath(architecture), QStringList()<<QLatin1String("--strip-unneeded") << file); + stripProcess.start(AndroidConfigurations::instance().stripPath(architecture).toString(), + QStringList()<<QLatin1String("--strip-unneeded") << file); stripProcess.waitForStarted(); if (!stripProcess.waitForFinished()) stripProcess.terminate(); @@ -573,7 +569,7 @@ void AndroidPackageCreationStep::certificatePassword() void AndroidPackageCreationStep::showInGraphicalShell() { - Core::FileUtils::showInGraphicalShell(Core::ICore::instance()->mainWindow(), m_apkPathSigned); + Core::FileUtils::showInGraphicalShell(Core::ICore::instance()->mainWindow(), m_apkPathSigned.toString()); } void AndroidPackageCreationStep::raiseError(const QString &shortMsg, diff --git a/src/plugins/android/androidpackagecreationstep.h b/src/plugins/android/androidpackagecreationstep.h index 9815d0be135..4c530c53af7 100644 --- a/src/plugins/android/androidpackagecreationstep.h +++ b/src/plugins/android/androidpackagecreationstep.h @@ -50,7 +50,6 @@ class Qt4BuildConfiguration; namespace Android { namespace Internal { -class AndroidTarget; class AndroidPackageCreationStep : public ProjectExplorer::BuildStep { @@ -66,14 +65,12 @@ public: static const QLatin1String DefaultVersionNumber; - AndroidTarget *androidTarget() const; - void checkRequiredLibraries(); void initCheckRequiredLibrariesForRun(); void checkRequiredLibrariesForRun(); - QString keystorePath(); - void setKeystorePath(const QString &path); + Utils::FileName keystorePath(); + void setKeystorePath(const Utils::FileName &path); void setKeystorePassword(const QString &pwd); void setCertificateAlias(const QString &alias); void setCertificatePassword(const QString &pwd); @@ -110,7 +107,7 @@ private: static const Core::Id CreatePackageId; private: - QString m_keystorePath; + Utils::FileName m_keystorePath; QString m_keystorePasswd; QString m_certificateAlias; QString m_certificatePasswd; @@ -118,19 +115,19 @@ private: JavaParser m_outputParser; // members to pass data from init() to run() - QString m_androidDir; - QString m_gdbServerSource; - QString m_gdbServerDestination; + Utils::FileName m_androidDir; + Utils::FileName m_gdbServerSource; + Utils::FileName m_gdbServerDestination; bool m_debugBuild; - QString m_antToolPath; - QString m_apkPathUnsigned; - QString m_apkPathSigned; - QString m_keystorePathForRun; + Utils::FileName m_antToolPath; + Utils::FileName m_apkPathUnsigned; + Utils::FileName m_apkPathSigned; + Utils::FileName m_keystorePathForRun; QString m_certificatePasswdForRun; - QString m_jarSigner; + Utils::FileName m_jarSigner; // more for checkLibraries - QString m_appPath; - QString m_readElf; + Utils::FileName m_appPath; + Utils::FileName m_readElf; QStringList m_qtLibs; QStringList m_availableQtLibs; QStringList m_prebundledLibs; diff --git a/src/plugins/android/androidpackagecreationwidget.cpp b/src/plugins/android/androidpackagecreationwidget.cpp index e1d62e0fe6b..046ec769f09 100644 --- a/src/plugins/android/androidpackagecreationwidget.cpp +++ b/src/plugins/android/androidpackagecreationwidget.cpp @@ -34,7 +34,7 @@ #include "androidpackagecreationstep.h" #include "androidconfigurations.h" #include "androidcreatekeystorecertificate.h" -#include "androidtarget.h" +#include "androidmanager.h" #include "ui_androidpackagecreationwidget.h" #include <projectexplorer/project.h> @@ -49,6 +49,7 @@ #include <QTimer> #include <QFileDialog> +#include <QFileSystemWatcher> #include <QMessageBox> namespace Android { @@ -203,7 +204,8 @@ int PermissionsModel::rowCount(const QModelIndex &parent) const AndroidPackageCreationWidget::AndroidPackageCreationWidget(AndroidPackageCreationStep *step) : ProjectExplorer::BuildStepConfigWidget(), m_step(step), - m_ui(new Ui::AndroidPackageCreationWidget) + m_ui(new Ui::AndroidPackageCreationWidget), + m_fileSystemWatcher(new QFileSystemWatcher(this)) { m_qtLibsModel = new CheckModel(this); m_prebundledLibs = new CheckModel(this); @@ -219,10 +221,16 @@ AndroidPackageCreationWidget::AndroidPackageCreationWidget(AndroidPackageCreatio void AndroidPackageCreationWidget::initGui() { updateAndroidProjectInfo(); - AndroidTarget *target = m_step->androidTarget(); - connect(target, - SIGNAL(androidDirContentsChanged()), - this, SLOT(updateAndroidProjectInfo())); + ProjectExplorer::Target *target = m_step->target(); + + m_fileSystemWatcher->addPath(AndroidManager::dirPath(target).toString()); + m_fileSystemWatcher->addPath(AndroidManager::manifestPath(target).toString()); + m_fileSystemWatcher->addPath(AndroidManager::srcPath(target).toString()); + connect(m_fileSystemWatcher, SIGNAL(directoryChanged(QString)), + this, SIGNAL(updateAndroidProjectInfo())); + connect(m_fileSystemWatcher, SIGNAL(fileChanged(QString)), this, + SIGNAL(updateAndroidProjectInfo())); + m_ui->packageNameLineEdit->setValidator(new QRegExpValidator(QRegExp(packageNameRegExp), this)); connect(m_ui->packageNameLineEdit, SIGNAL(editingFinished()), SLOT(setPackageName())); connect(m_ui->appNameLineEdit, SIGNAL(editingFinished()), SLOT(setApplicationName())); @@ -251,49 +259,50 @@ void AndroidPackageCreationWidget::initGui() m_ui->qtLibsListView->setModel(m_qtLibsModel); m_ui->prebundledLibsListView->setModel(m_prebundledLibs); m_ui->permissionsListView->setModel(m_permissionsModel); - m_ui->KeystoreLocationLineEdit->setText(m_step->keystorePath()); + m_ui->KeystoreLocationLineEdit->setText(m_step->keystorePath().toUserOutput()); } void AndroidPackageCreationWidget::updateAndroidProjectInfo() { - AndroidTarget *target = m_step->androidTarget(); + ProjectExplorer::Target *target = m_step->target(); + const QString packageName = AndroidManager::packageName(target); m_ui->targetSDKComboBox->clear(); QStringList targets = AndroidConfigurations::instance().sdkTargets(); m_ui->targetSDKComboBox->addItems(targets); - m_ui->targetSDKComboBox->setCurrentIndex(targets.indexOf(target->targetSDK())); - m_ui->packageNameLineEdit->setText(target->packageName()); - m_ui->appNameLineEdit->setText(target->applicationName()); + m_ui->targetSDKComboBox->setCurrentIndex(targets.indexOf(AndroidManager::targetSDK(target))); + m_ui->packageNameLineEdit->setText(packageName); + m_ui->appNameLineEdit->setText(AndroidManager::applicationName(target)); if (!m_ui->appNameLineEdit->text().length()) { QString applicationName = target->project()->displayName(); - target->setPackageName(target->packageName() + QLatin1Char('.') + applicationName); - m_ui->packageNameLineEdit->setText(target->packageName()); - if (applicationName.length()) + AndroidManager::setPackageName(target, packageName + QLatin1Char('.') + applicationName); + m_ui->packageNameLineEdit->setText(packageName); + if (!applicationName.isEmpty()) applicationName[0] = applicationName[0].toUpper(); m_ui->appNameLineEdit->setText(applicationName); - target->setApplicationName(applicationName); + AndroidManager::setApplicationName(target, applicationName); } - m_ui->versionCode->setValue(target->versionCode()); - m_ui->versionNameLinedit->setText(target->versionName()); + m_ui->versionCode->setValue(AndroidManager::versionCode(target)); + m_ui->versionNameLinedit->setText(AndroidManager::versionName(target)); - m_qtLibsModel->setAvailableItems(target->availableQtLibs()); - m_qtLibsModel->setCheckedItems(target->qtLibs()); - m_prebundledLibs->setAvailableItems(target->availablePrebundledLibs()); - m_prebundledLibs->setCheckedItems(target->prebundledLibs()); + m_qtLibsModel->setAvailableItems(AndroidManager::availableQtLibs(target)); + m_qtLibsModel->setCheckedItems(AndroidManager::qtLibs(target)); + m_prebundledLibs->setAvailableItems(AndroidManager::availablePrebundledLibs(target)); + m_prebundledLibs->setCheckedItems(AndroidManager::prebundledLibs(target)); - m_permissionsModel->setPermissions(target->permissions()); + m_permissionsModel->setPermissions(AndroidManager::permissions(target)); m_ui->removePermissionButton->setEnabled(m_permissionsModel->permissions().size()); - targets = target->availableTargetApplications(); + targets = AndroidManager::availableTargetApplications(target); m_ui->targetComboBox->clear(); m_ui->targetComboBox->addItems(targets); - m_ui->targetComboBox->setCurrentIndex(targets.indexOf(target->targetApplication())); + m_ui->targetComboBox->setCurrentIndex(targets.indexOf(AndroidManager::targetApplication(target))); if (m_ui->targetComboBox->currentIndex() == -1 && targets.count()) { m_ui->targetComboBox->setCurrentIndex(0); - target->setTargetApplication(m_ui->targetComboBox->currentText()); + AndroidManager::setTargetApplication(target, m_ui->targetComboBox->currentText()); } - m_ui->hIconButton->setIcon(target->highDpiIcon()); - m_ui->mIconButton->setIcon(target->mediumDpiIcon()); - m_ui->lIconButton->setIcon(target->lowDpiIcon()); + m_ui->hIconButton->setIcon(AndroidManager::highDpiIcon(target)); + m_ui->mIconButton->setIcon(AndroidManager::mediumDpiIcon(target)); + m_ui->lIconButton->setIcon(AndroidManager::lowDpiIcon(target)); } void AndroidPackageCreationWidget::setPackageName() @@ -308,26 +317,27 @@ void AndroidPackageCreationWidget::setPackageName() m_ui->packageNameLineEdit->setFocus(); return; } - m_step->androidTarget()->setPackageName(packageName); + AndroidManager::setPackageName(m_step->target(), packageName); } void AndroidPackageCreationWidget::setApplicationName() { - m_step->androidTarget()->setApplicationName(m_ui->appNameLineEdit->text()); + AndroidManager::setApplicationName(m_step->target(), m_ui->appNameLineEdit->text()); } -void AndroidPackageCreationWidget::setTargetSDK(const QString &target) +void AndroidPackageCreationWidget::setTargetSDK(const QString &sdk) { - m_step->androidTarget()->setTargetSDK(target); - Qt4BuildConfiguration *bc = m_step->androidTarget()->activeQt4BuildConfiguration(); - ProjectExplorer::BuildManager *bm = ProjectExplorer::ProjectExplorerPlugin::instance()->buildManager(); + AndroidManager::setTargetSDK(m_step->target(), sdk); + Qt4BuildConfiguration *bc = qobject_cast<Qt4BuildConfiguration *>(m_step->target()->activeBuildConfiguration()); + if (!bc) + return; QMakeStep *qs = bc->qmakeStep(); - if (!qs) return; qs->setForced(true); + ProjectExplorer::BuildManager *bm = ProjectExplorer::ProjectExplorerPlugin::instance()->buildManager(); bm->buildList(bc->stepList(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_CLEAN)), ProjectExplorer::ProjectExplorerPlugin::displayNameForStepId(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_CLEAN))); bm->appendStep(qs, ProjectExplorer::ProjectExplorerPlugin::displayNameForStepId(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_CLEAN))); @@ -341,27 +351,27 @@ void AndroidPackageCreationWidget::setTargetSDK(const QString &target) void AndroidPackageCreationWidget::setVersionCode() { - m_step->androidTarget()->setVersionCode(m_ui->versionCode->value()); + AndroidManager::setVersionCode(m_step->target(), m_ui->versionCode->value()); } void AndroidPackageCreationWidget::setVersionName() { - m_step->androidTarget()->setVersionName(m_ui->versionNameLinedit->text()); + AndroidManager::setVersionName(m_step->target(), m_ui->versionNameLinedit->text()); } void AndroidPackageCreationWidget::setTarget(const QString &target) { - m_step->androidTarget()->setTargetApplication(target); + AndroidManager::setTargetApplication(m_step->target(), target); } void AndroidPackageCreationWidget::setQtLibs(QModelIndex, QModelIndex) { - m_step->androidTarget()->setQtLibs(m_qtLibsModel->checkedItems()); + AndroidManager::setQtLibs(m_step->target(), m_qtLibsModel->checkedItems()); } void AndroidPackageCreationWidget::setPrebundledLibs(QModelIndex, QModelIndex) { - m_step->androidTarget()->setPrebundledLibs(m_prebundledLibs->checkedItems()); + AndroidManager::setPrebundledLibs(m_step->target(), m_prebundledLibs->checkedItems()); } void AndroidPackageCreationWidget::prebundledLibSelected(const QModelIndex &index) @@ -395,8 +405,8 @@ void AndroidPackageCreationWidget::setHDPIIcon() QString file = QFileDialog::getOpenFileName(this, tr("Choose High DPI Icon"), QDir::homePath(), tr("png images (*.png)")); if (!file.length()) return; - m_step->androidTarget()->setHighDpiIcon(file); - m_ui->hIconButton->setIcon(m_step->androidTarget()->highDpiIcon()); + AndroidManager::setHighDpiIcon(m_step->target(), file); + m_ui->hIconButton->setIcon(AndroidManager::highDpiIcon(m_step->target())); } void AndroidPackageCreationWidget::setMDPIIcon() @@ -404,8 +414,8 @@ void AndroidPackageCreationWidget::setMDPIIcon() QString file = QFileDialog::getOpenFileName(this, tr("Choose Medium DPI Icon"), QDir::homePath(), tr("png images (*.png)")); if (!file.length()) return; - m_step->androidTarget()->setMediumDpiIcon(file); - m_ui->mIconButton->setIcon(m_step->androidTarget()->mediumDpiIcon()); + AndroidManager::setMediumDpiIcon(m_step->target(), file); + m_ui->mIconButton->setIcon(AndroidManager::mediumDpiIcon(m_step->target())); } void AndroidPackageCreationWidget::setLDPIIcon() @@ -413,8 +423,8 @@ void AndroidPackageCreationWidget::setLDPIIcon() QString file = QFileDialog::getOpenFileName(this, tr("Choose Low DPI Icon"), QDir::homePath(), tr("png images (*.png)")); if (!file.length()) return; - m_step->androidTarget()->setLowDpiIcon(file); - m_ui->lIconButton->setIcon(m_step->androidTarget()->lowDpiIcon()); + AndroidManager::setLowDpiIcon(m_step->target(), file); + m_ui->lIconButton->setIcon(AndroidManager::lowDpiIcon(m_step->target())); } void AndroidPackageCreationWidget::permissionActivated(QModelIndex index) @@ -451,21 +461,21 @@ void AndroidPackageCreationWidget::removePermission() void AndroidPackageCreationWidget::savePermissionsButton() { setEnabledSaveDiscardButtons(false); - m_step->androidTarget()->setPermissions(m_permissionsModel->permissions()); + AndroidManager::setPermissions(m_step->target(), m_permissionsModel->permissions()); } void AndroidPackageCreationWidget::discardPermissionsButton() { setEnabledSaveDiscardButtons(false); - m_permissionsModel->setPermissions(m_step->androidTarget()->permissions()); + m_permissionsModel->setPermissions(AndroidManager::permissions(m_step->target())); m_ui->permissionsComboBox->setCurrentIndex(-1); m_ui->removePermissionButton->setEnabled(m_permissionsModel->permissions().size()); } void AndroidPackageCreationWidget::updateRequiredLibrariesModels() { - m_qtLibsModel->setCheckedItems(m_step->androidTarget()->qtLibs()); - m_prebundledLibs->setCheckedItems(m_step->androidTarget()->prebundledLibs()); + m_qtLibsModel->setCheckedItems(AndroidManager::qtLibs(m_step->target())); + m_prebundledLibs->setCheckedItems(AndroidManager::prebundledLibs(m_step->target())); } void AndroidPackageCreationWidget::readElfInfo() @@ -502,7 +512,7 @@ void AndroidPackageCreationWidget::on_signPackageCheckBox_toggled(bool checked) { if (!checked) return; - if (m_step->keystorePath().length()) + if (!m_step->keystorePath().isEmpty()) setCertificates(); } @@ -511,7 +521,7 @@ void AndroidPackageCreationWidget::on_KeystoreCreatePushButton_clicked() AndroidCreateKeystoreCertificate d; if (d.exec() != QDialog::Accepted) return; - m_ui->KeystoreLocationLineEdit->setText(d.keystoreFilePath()); + m_ui->KeystoreLocationLineEdit->setText(d.keystoreFilePath().toUserOutput()); m_step->setKeystorePath(d.keystoreFilePath()); m_step->setKeystorePassword(d.keystorePassword()); m_step->setCertificateAlias(d.certificateAlias()); @@ -521,13 +531,13 @@ void AndroidPackageCreationWidget::on_KeystoreCreatePushButton_clicked() void AndroidPackageCreationWidget::on_KeystoreLocationPushButton_clicked() { - QString keystorePath = m_step->keystorePath(); - if (!keystorePath.length()) - keystorePath = QDir::homePath(); - QString file = QFileDialog::getOpenFileName(this, tr("Select Keystore File"), keystorePath, tr("Keystore files (*.keystore *.jks)")); - if (!file.length()) + Utils::FileName keystorePath = m_step->keystorePath(); + if (keystorePath.isEmpty()) + keystorePath = Utils::FileName::fromString(QDir::homePath()); + Utils::FileName file = Utils::FileName::fromString(QFileDialog::getOpenFileName(this, tr("Select keystore file"), keystorePath.toString(), tr("Keystore files (*.keystore *.jks)"))); + if (file.isEmpty()) return; - m_ui->KeystoreLocationLineEdit->setText(file); + m_ui->KeystoreLocationLineEdit->setText(file.toUserOutput()); m_step->setKeystorePath(file); m_ui->signPackageCheckBox->setChecked(false); } @@ -551,6 +561,3 @@ void AndroidPackageCreationWidget::on_openPackageLocationCheckBox_toggled(bool c } // namespace Internal } // namespace Android - - - diff --git a/src/plugins/android/androidpackagecreationwidget.h b/src/plugins/android/androidpackagecreationwidget.h index 59ca55ce86d..971f36383c5 100644 --- a/src/plugins/android/androidpackagecreationwidget.h +++ b/src/plugins/android/androidpackagecreationwidget.h @@ -38,6 +38,8 @@ #include <QStringList> QT_BEGIN_NAMESPACE +class QFileSystemWatcher; + namespace Ui { class AndroidPackageCreationWidget; } QT_END_NAMESPACE @@ -106,7 +108,7 @@ private slots: void setPackageName(); void setApplicationName(); - void setTargetSDK(const QString &target); + void setTargetSDK(const QString &sdk); void setVersionCode(); void setVersionName(); void setTarget(const QString &target); @@ -142,6 +144,7 @@ private: CheckModel *m_qtLibsModel; CheckModel *m_prebundledLibs; PermissionsModel *m_permissionsModel; + QFileSystemWatcher *m_fileSystemWatcher; }; } // namespace Internal diff --git a/src/plugins/android/androidpackageinstallationfactory.cpp b/src/plugins/android/androidpackageinstallationfactory.cpp index 448746e5b76..641252f248f 100644 --- a/src/plugins/android/androidpackageinstallationfactory.cpp +++ b/src/plugins/android/androidpackageinstallationfactory.cpp @@ -33,11 +33,13 @@ #include "androidpackageinstallationfactory.h" #include "androidpackageinstallationstep.h" +#include "androidmanager.h" #include <projectexplorer/buildsteplist.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/target.h> -#include <qt4projectmanager/qt4projectmanagerconstants.h> +#include <qtsupport/qtprofileinformation.h> +#include <qtsupport/qtsupportconstants.h> #include <QCoreApplication> @@ -53,11 +55,13 @@ AndroidPackageInstallationFactory::AndroidPackageInstallationFactory(QObject *pa QList<Core::Id> AndroidPackageInstallationFactory::availableCreationIds(BuildStepList *parent) const { - if (parent->id() == Core::Id(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY) - && parent->target()->id() == Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID) - && !parent->contains(Core::Id(AndroidPackageInstallationStep::Id))) - return QList<Core::Id>() << Core::Id(AndroidPackageInstallationStep::Id); - return QList<Core::Id>(); + if (parent->id() != Core::Id(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY)) + return QList<Core::Id>(); + if (!AndroidManager::supportsAndroid(parent->target())) + return QList<Core::Id>(); + if (parent->contains(AndroidPackageInstallationStep::Id)) + return QList<Core::Id>(); + return QList<Core::Id>() << AndroidPackageInstallationStep::Id; } QString AndroidPackageInstallationFactory::displayNameForId(const Core::Id id) const @@ -70,10 +74,7 @@ QString AndroidPackageInstallationFactory::displayNameForId(const Core::Id id) c bool AndroidPackageInstallationFactory::canCreate(BuildStepList *parent, const Core::Id id) const { - return parent->id() == Core::Id(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY) - && id == Core::Id(AndroidPackageInstallationStep::Id) - && parent->target()->id() == Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID) - && !parent->contains(AndroidPackageInstallationStep::Id); + return availableCreationIds(parent).contains(id); } BuildStep *AndroidPackageInstallationFactory::create(BuildStepList *parent, const Core::Id id) diff --git a/src/plugins/android/androidpackageinstallationstep.cpp b/src/plugins/android/androidpackageinstallationstep.cpp index f1a1efc4ca5..b3029a29b21 100644 --- a/src/plugins/android/androidpackageinstallationstep.cpp +++ b/src/plugins/android/androidpackageinstallationstep.cpp @@ -31,7 +31,7 @@ **************************************************************************/ #include "androidpackageinstallationstep.h" -#include "androidtarget.h" +#include "androidmanager.h" #include <QFileInfo> #include <QDir> @@ -54,25 +54,13 @@ AndroidPackageInstallationStep::AndroidPackageInstallationStep(ProjectExplorer:: } AndroidPackageInstallationStep::AndroidPackageInstallationStep(ProjectExplorer::BuildStepList *bc, AndroidPackageInstallationStep *other): MakeStep(bc, other) -{ - const QString name = stepDisplayName(); - setDefaultDisplayName(name); - setDisplayName(name); -} +{ } AndroidPackageInstallationStep::~AndroidPackageInstallationStep() -{ -} +{ } bool AndroidPackageInstallationStep::init() { - AndroidTarget *androidTarget = qobject_cast<AndroidTarget *>(target()); - if (!androidTarget) { - emit addOutput(tr("Current target is not an Android target"), BuildStep::MessageOutput); - return false; - } - - setUserArguments(QString::fromLatin1("INSTALL_ROOT=\"%1\" install").arg(QDir::toNativeSeparators(androidTarget->androidDirPath()))); - + setUserArguments(QString::fromLatin1("INSTALL_ROOT=\"%1\" install").arg(AndroidManager::dirPath(target()).toUserOutput())); return MakeStep::init(); } diff --git a/src/plugins/android/androidplugin.cpp b/src/plugins/android/androidplugin.cpp index 6f27c8c8cff..37703f8558e 100644 --- a/src/plugins/android/androidplugin.cpp +++ b/src/plugins/android/androidplugin.cpp @@ -36,51 +36,50 @@ #include "androidconfigurations.h" #include "androiddeploystepfactory.h" #include "androidconfigurations.h" +#include "androidmanager.h" #include "androidpackagecreationfactory.h" #include "androidpackageinstallationfactory.h" #include "androidrunfactories.h" #include "androidsettingspage.h" #include "androidtoolchain.h" #include "androidqtversionfactory.h" -#include "androidtargetfactory.h" #include "androiddeployconfiguration.h" #include <QtPlugin> -using namespace Android; -using namespace Android::Internal; +namespace Android { AndroidPlugin::AndroidPlugin() -{ -} +{ } AndroidPlugin::~AndroidPlugin() -{ -} +{ } bool AndroidPlugin::initialize(const QStringList &arguments, - QString *error_message) + QString *error_message) { - Q_UNUSED(arguments) - Q_UNUSED(error_message) + Q_UNUSED(arguments); + Q_UNUSED(error_message); - AndroidConfigurations::instance(this); + Internal::AndroidConfigurations::instance(this); - addAutoReleasedObject(new AndroidRunControlFactory); - addAutoReleasedObject(new AndroidRunConfigurationFactory); - addAutoReleasedObject(new AndroidPackageInstallationFactory); - addAutoReleasedObject(new AndroidPackageCreationFactory); - addAutoReleasedObject(new AndroidDeployStepFactory); - addAutoReleasedObject(new AndroidSettingsPage); - addAutoReleasedObject(new AndroidTargetFactory); - addAutoReleasedObject(new AndroidQtVersionFactory); - addAutoReleasedObject(new AndroidToolChainFactory); - addAutoReleasedObject(new AndroidDeployConfigurationFactory); + new Internal::AndroidManager(this); + + addAutoReleasedObject(new Internal::AndroidRunControlFactory); + addAutoReleasedObject(new Internal::AndroidRunConfigurationFactory); + addAutoReleasedObject(new Internal::AndroidPackageInstallationFactory); + addAutoReleasedObject(new Internal::AndroidPackageCreationFactory); + addAutoReleasedObject(new Internal::AndroidDeployStepFactory); + addAutoReleasedObject(new Internal::AndroidSettingsPage); + addAutoReleasedObject(new Internal::AndroidQtVersionFactory); + addAutoReleasedObject(new Internal::AndroidToolChainFactory); + addAutoReleasedObject(new Internal::AndroidDeployConfigurationFactory); return true; } void AndroidPlugin::extensionsInitialized() -{ -} +{ } + +} // namespace Android Q_EXPORT_PLUGIN(Android::AndroidPlugin) diff --git a/src/plugins/android/androidplugin.h b/src/plugins/android/androidplugin.h index c8ad7c4a9cf..e9a049f74c7 100644 --- a/src/plugins/android/androidplugin.h +++ b/src/plugins/android/androidplugin.h @@ -30,8 +30,8 @@ ** **************************************************************************/ -#ifndef ANDROIDMANAGER_H -#define ANDROIDMANAGER_H +#ifndef ANDROIDPLUGIN_H +#define ANDROIDPLUGIN_H #include <extensionsystem/iplugin.h> @@ -47,8 +47,8 @@ public: bool initialize(const QStringList &arguments, QString *error_message); void extensionsInitialized(); - }; -} // namespace Qt4ProjectManager -#endif // ANDROIDMANAGER_H +} // namespace Android + +#endif // ANDROIDPLUGIN_H diff --git a/src/plugins/android/androidqtversion.cpp b/src/plugins/android/androidqtversion.cpp index 9fa3f795c42..6571faa10de 100644 --- a/src/plugins/android/androidqtversion.cpp +++ b/src/plugins/android/androidqtversion.cpp @@ -90,16 +90,6 @@ QList<ProjectExplorer::Abi> AndroidQtVersion::detectQtAbis() const 32); } -bool AndroidQtVersion::supportsTargetId(const Core::Id id) const -{ - return id == Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID); -} - -QSet<Core::Id> AndroidQtVersion::supportedTargetIds() const -{ - return QSet<Core::Id>() << Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID); -} - QString AndroidQtVersion::description() const { return QCoreApplication::translate("QtVersion", "Android", "Qt Version is meant for Android"); @@ -114,10 +104,10 @@ Core::FeatureSet AndroidQtVersion::availableFeatures() const QString AndroidQtVersion::platformName() const { - return QLatin1String(Constants::ANDROID_PLATFORM); + return QLatin1String(QtSupport::Constants::ANDROID_PLATFORM); } QString AndroidQtVersion::platformDisplayName() const { - return QLatin1String(Constants::ANDROID_PLATFORM_TR); + return QLatin1String(QtSupport::Constants::ANDROID_PLATFORM_TR); } diff --git a/src/plugins/android/androidqtversion.h b/src/plugins/android/androidqtversion.h index be6f6800fa9..486cacd6470 100644 --- a/src/plugins/android/androidqtversion.h +++ b/src/plugins/android/androidqtversion.h @@ -52,9 +52,6 @@ public: QList<ProjectExplorer::Abi> detectQtAbis() const; - bool supportsTargetId(const Core::Id id) const; - QSet<Core::Id> supportedTargetIds() const; - Core::FeatureSet availableFeatures() const; QString platformName() const; QString platformDisplayName() const; diff --git a/src/plugins/android/androidrunconfiguration.cpp b/src/plugins/android/androidrunconfiguration.cpp index 0b33498543b..db27ab87363 100644 --- a/src/plugins/android/androidrunconfiguration.cpp +++ b/src/plugins/android/androidrunconfiguration.cpp @@ -34,14 +34,19 @@ #include "androiddeploystep.h" #include "androidglobal.h" #include "androidtoolchain.h" -#include "androidtarget.h" +#include "androidmanager.h" +#include <projectexplorer/profileinformation.h> +#include <projectexplorer/target.h> #include <qt4projectmanager/qt4buildconfiguration.h> #include <qt4projectmanager/qt4project.h> +#include <qtsupport/qtprofileinformation.h> + #include <utils/qtcassert.h> #include <qtsupport/qtoutputformatter.h> +#include <qtsupport/qtprofileinformation.h> using namespace Qt4ProjectManager; @@ -50,15 +55,14 @@ namespace Internal { using namespace ProjectExplorer; -AndroidRunConfiguration::AndroidRunConfiguration(AndroidTarget *parent, - const QString &proFilePath) - : RunConfiguration(parent, Core::Id(ANDROID_RC_ID)) - , m_proFilePath(proFilePath) +AndroidRunConfiguration::AndroidRunConfiguration(Target *parent, Core::Id id, const QString &path) + : RunConfiguration(parent, id) + , m_proFilePath(path) { init(); } -AndroidRunConfiguration::AndroidRunConfiguration(AndroidTarget *parent, +AndroidRunConfiguration::AndroidRunConfiguration(ProjectExplorer::Target *parent, AndroidRunConfiguration *source) : RunConfiguration(parent, source) , m_proFilePath(source->m_proFilePath) @@ -75,11 +79,6 @@ AndroidRunConfiguration::~AndroidRunConfiguration() { } -AndroidTarget *AndroidRunConfiguration::androidTarget() const -{ - return static_cast<AndroidTarget *>(target()); -} - Qt4BuildConfiguration *AndroidRunConfiguration::activeQt4BuildConfiguration() const { return static_cast<Qt4BuildConfiguration *>(activeBuildConfiguration()); @@ -92,7 +91,7 @@ QWidget *AndroidRunConfiguration::createConfigurationWidget() Utils::OutputFormatter *AndroidRunConfiguration::createOutputFormatter() const { - return new QtSupport::QtOutputFormatter(androidTarget()->qt4Project()); + return new QtSupport::QtOutputFormatter(target()->project()); } QString AndroidRunConfiguration::defaultDisplayName() @@ -105,9 +104,12 @@ AndroidConfig AndroidRunConfiguration::config() const return AndroidConfigurations::instance().config(); } -const QString AndroidRunConfiguration::gdbCmd() const +const Utils::FileName AndroidRunConfiguration::gdbCmd() const { - return AndroidConfigurations::instance().gdbPath(activeQt4BuildConfiguration()->toolChain()->targetAbi().architecture()); + ToolChain *tc = ToolChainProfileInformation::toolChain(target()->profile()); + if (!tc) + return Utils::FileName(); + return AndroidConfigurations::instance().gdbPath(tc->targetAbi().architecture()); } AndroidDeployStep *AndroidRunConfiguration::deployStep() const @@ -127,8 +129,10 @@ const QString AndroidRunConfiguration::remoteChannel() const const QString AndroidRunConfiguration::dumperLib() const { - Qt4BuildConfiguration *qt4bc(activeQt4BuildConfiguration()); - return qt4bc->qtVersion()->gdbDebuggingHelperLibrary(); + QtSupport::BaseQtVersion *version = QtSupport::QtProfileInformation::qtVersion(target()->profile()); + if (!version) + return QString(); + return version->gdbDebuggingHelperLibrary(); } QString AndroidRunConfiguration::proFilePath() const diff --git a/src/plugins/android/androidrunconfiguration.h b/src/plugins/android/androidrunconfiguration.h index 1e34fac4577..b62ee11ef2e 100644 --- a/src/plugins/android/androidrunconfiguration.h +++ b/src/plugins/android/androidrunconfiguration.h @@ -56,7 +56,6 @@ class AndroidDeviceConfigListModel; class AndroidDeployStep; class AndroidRunConfigurationFactory; class AndroidToolChain; -class AndroidTarget; class AndroidRunConfiguration : public ProjectExplorer::RunConfiguration { @@ -71,12 +70,11 @@ public: enum DebuggingType { DebugCppOnly, DebugQmlOnly, DebugCppAndQml }; - AndroidRunConfiguration(AndroidTarget *parent, const QString &proFilePath); + AndroidRunConfiguration(ProjectExplorer::Target *parent, Core::Id id, const QString &path); virtual ~AndroidRunConfiguration(); QWidget *createConfigurationWidget(); Utils::OutputFormatter *createOutputFormatter() const; - AndroidTarget *androidTarget() const; Qt4ProjectManager::Qt4BuildConfiguration *activeQt4BuildConfiguration() const; AndroidDeployStep *deployStep() const; @@ -87,12 +85,12 @@ public: DebuggingType debuggingType() const; - const QString gdbCmd() const; + const Utils::FileName gdbCmd() const; const QString remoteChannel() const; const QString dumperLib() const; protected: - AndroidRunConfiguration(AndroidTarget *parent, AndroidRunConfiguration *source); + AndroidRunConfiguration(ProjectExplorer::Target *parent, AndroidRunConfiguration *source); QString defaultDisplayName(); private: diff --git a/src/plugins/android/androidrunfactories.cpp b/src/plugins/android/androidrunfactories.cpp index 1feeb410c72..d5764669797 100644 --- a/src/plugins/android/androidrunfactories.cpp +++ b/src/plugins/android/androidrunfactories.cpp @@ -36,13 +36,17 @@ #include "androiddebugsupport.h" #include "androidrunconfiguration.h" #include "androidruncontrol.h" -#include "androidtarget.h" +#include "androidmanager.h" +#include <projectexplorer/project.h> #include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/target.h> #include <debugger/debuggerconstants.h> #include <qt4projectmanager/qt4project.h> #include <qt4projectmanager/qt4nodes.h> -#include <qt4projectmanager/qt4projectmanagerconstants.h> +#include <qtsupport/customexecutablerunconfiguration.h> +#include <qtsupport/qtprofileinformation.h> +#include <qtsupport/qtsupportconstants.h> namespace Android { @@ -55,7 +59,7 @@ namespace { QString pathFromId(const Core::Id id) { - QString pathStr = QString::fromUtf8(id.name()); + QString pathStr = id.toString(); const QString prefix = QLatin1String(ANDROID_RC_ID_PREFIX); if (!pathStr.startsWith(prefix)) return QString(); @@ -65,34 +69,25 @@ QString pathFromId(const Core::Id id) } // namespace AndroidRunConfigurationFactory::AndroidRunConfigurationFactory(QObject *parent) - : IRunConfigurationFactory(parent) -{ -} + : QmakeRunConfigurationFactory(parent) +{ setObjectName(QLatin1String("AndroidRunConfigurationFactory")); } AndroidRunConfigurationFactory::~AndroidRunConfigurationFactory() -{ -} +{ } -bool AndroidRunConfigurationFactory::canCreate(Target *parent, - const Core::Id/*id*/) const +bool AndroidRunConfigurationFactory::canCreate(Target *parent, const Core::Id id) const { - AndroidTarget *target = qobject_cast<AndroidTarget *>(parent); - if (!target - || target->id() != Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID)) { + if (!canHandle(parent)) return false; - } - return true; + return availableCreationIds(parent).contains(id); } -bool AndroidRunConfigurationFactory::canRestore(Target *parent, - const QVariantMap &map) const +bool AndroidRunConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const { - Q_UNUSED(parent) - Q_UNUSED(map) - if (!qobject_cast<AndroidTarget *>(parent)) + if (!canHandle(parent)) return false; - QString id = QString::fromUtf8(ProjectExplorer::idFromMap(map).name()); - return id.startsWith(QLatin1String(ANDROID_RC_ID)); + QString id = ProjectExplorer::idFromMap(map).toString(); + return id.startsWith(QLatin1String(ANDROID_RC_ID_PREFIX)); } bool AndroidRunConfigurationFactory::canClone(Target *parent, @@ -104,14 +99,12 @@ bool AndroidRunConfigurationFactory::canClone(Target *parent, QList<Core::Id> AndroidRunConfigurationFactory::availableCreationIds(Target *parent) const { QList<Core::Id> ids; - if (AndroidTarget *t = qobject_cast<AndroidTarget *>(parent)) { - if (t->id() == Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID)) { - QList<Qt4ProFileNode *> nodes = t->qt4Project()->allProFiles(); - foreach (Qt4ProFileNode *node, nodes) - if (node->projectType() == ApplicationTemplate || node->projectType() == LibraryTemplate) - ids << Core::Id(node->targetInformation().target); - } - } + if (!AndroidManager::supportsAndroid(parent)) + return ids; + QList<Qt4ProFileNode *> nodes = static_cast<Qt4Project *>(parent->project())->allProFiles(); + foreach (Qt4ProFileNode *node, nodes) + if (node->projectType() == ApplicationTemplate || node->projectType() == LibraryTemplate) + ids << Core::Id(node->targetInformation().target); return ids; } @@ -120,14 +113,11 @@ QString AndroidRunConfigurationFactory::displayNameForId(const Core::Id id) cons return QFileInfo(pathFromId(id)).completeBaseName(); } -RunConfiguration *AndroidRunConfigurationFactory::create(Target *parent, - const Core::Id id) +RunConfiguration *AndroidRunConfigurationFactory::create(Target *parent, const Core::Id id) { if (!canCreate(parent, id)) return 0; - AndroidTarget *pqt4parent = static_cast<AndroidTarget *>(parent); - return new AndroidRunConfiguration(pqt4parent, pathFromId(id)); - + return new AndroidRunConfiguration(parent, id, pathFromId(id)); } RunConfiguration *AndroidRunConfigurationFactory::restore(Target *parent, @@ -135,8 +125,8 @@ RunConfiguration *AndroidRunConfigurationFactory::restore(Target *parent, { if (!canRestore(parent, map)) return 0; - AndroidTarget *target = static_cast<AndroidTarget *>(parent); - AndroidRunConfiguration *rc = new AndroidRunConfiguration(target, QString()); + Core::Id id = ProjectExplorer::idFromMap(map); + AndroidRunConfiguration *rc = new AndroidRunConfiguration(parent, id, pathFromId(id)); if (rc->fromMap(map)) return rc; @@ -144,14 +134,30 @@ RunConfiguration *AndroidRunConfigurationFactory::restore(Target *parent, return 0; } -RunConfiguration *AndroidRunConfigurationFactory::clone(Target *parent, - RunConfiguration *source) +RunConfiguration *AndroidRunConfigurationFactory::clone(Target *parent, RunConfiguration *source) { if (!canClone(parent, source)) return 0; AndroidRunConfiguration *old = static_cast<AndroidRunConfiguration *>(source); - return new AndroidRunConfiguration(static_cast<AndroidTarget *>(parent), old); + return new AndroidRunConfiguration(parent, old); +} + +bool AndroidRunConfigurationFactory::canHandle(Target *t) const +{ + if (!t->project()->supportsProfile(t->profile())) + return false; + return AndroidManager::supportsAndroid(t); +} + +QList<RunConfiguration *> AndroidRunConfigurationFactory::runConfigurationsForNode(Target *t, ProjectExplorer::Node *n) +{ + QList<ProjectExplorer::RunConfiguration *> result; + foreach (ProjectExplorer::RunConfiguration *rc, t->runConfigurations()) + if (AndroidRunConfiguration *qt4c = qobject_cast<AndroidRunConfiguration *>(rc)) + if (qt4c->proFilePath() == n->path()) + result << rc; + return result; } // #pragma mark -- AndroidRunControlFactory diff --git a/src/plugins/android/androidrunfactories.h b/src/plugins/android/androidrunfactories.h index fb4ffd40a29..04dc9df80e5 100644 --- a/src/plugins/android/androidrunfactories.h +++ b/src/plugins/android/androidrunfactories.h @@ -34,24 +34,26 @@ #define ANDROIDRUNFACTORIES_H #include <projectexplorer/runconfiguration.h> +#include <qt4projectmanager/qmakerunconfigurationfactory.h> namespace ProjectExplorer { - class RunConfiguration; class RunControl; class RunConfigWidget; class Target; } -using ProjectExplorer::IRunConfigurationFactory; + using ProjectExplorer::IRunControlFactory; using ProjectExplorer::RunConfiguration; using ProjectExplorer::RunControl; using ProjectExplorer::RunConfigWidget; using ProjectExplorer::Target; +namespace ProjectExplorer { class Node; } + namespace Android { namespace Internal { -class AndroidRunConfigurationFactory : public IRunConfigurationFactory +class AndroidRunConfigurationFactory : public Qt4ProjectManager::QmakeRunConfigurationFactory { Q_OBJECT @@ -70,6 +72,10 @@ public: bool canClone(Target *parent, RunConfiguration *source) const; RunConfiguration *clone(Target *parent, RunConfiguration *source); + + bool canHandle(ProjectExplorer::Target *t) const; + QList<ProjectExplorer::RunConfiguration *> runConfigurationsForNode(ProjectExplorer::Target *t, + ProjectExplorer::Node *n); }; class AndroidRunControlFactory : public IRunControlFactory diff --git a/src/plugins/android/androidrunner.cpp b/src/plugins/android/androidrunner.cpp index fe578c4ff8e..1a153447053 100644 --- a/src/plugins/android/androidrunner.cpp +++ b/src/plugins/android/androidrunner.cpp @@ -36,7 +36,9 @@ #include "androidconfigurations.h" #include "androidglobal.h" #include "androidrunconfiguration.h" -#include "androidtarget.h" +#include "androidmanager.h" + +#include <projectexplorer/target.h> #include <QTime> #include <QtConcurrentRun> @@ -49,13 +51,13 @@ AndroidRunner::AndroidRunner(QObject *parent, : QThread(parent) { m_remoteChannel = runConfig->remoteChannel(); - AndroidTarget * at = runConfig->androidTarget(); - AndroidDeployStep * ds = runConfig->deployStep(); + ProjectExplorer::Target *target = runConfig->target(); + AndroidDeployStep *ds = runConfig->deployStep(); if ((m_useLocalQtLibs = ds->useLocalQtLibs())) { - m_localLibs = at->loadLocalLibs(ds->deviceAPILevel()); - m_localJars = at->loadLocalJars(ds->deviceAPILevel()); + m_localLibs = AndroidManager::loadLocalLibs(target, ds->deviceAPILevel()); + m_localJars = AndroidManager::loadLocalJars(target, ds->deviceAPILevel()); } - m_intentName = at->intentName(); + m_intentName = AndroidManager::intentName(target); m_debugingMode = debugging; m_packageName = m_intentName.left(m_intentName.indexOf(QLatin1Char('/'))); m_deviceSerialNumber = ds->deviceSerialNumber(); @@ -74,7 +76,7 @@ AndroidRunner::~AndroidRunner() void AndroidRunner::checkPID() { QProcess psProc; - psProc.start(AndroidConfigurations::instance().adbToolPath(), + psProc.start(AndroidConfigurations::instance().adbToolPath().toString(), QStringList() << QLatin1String("-s") << m_deviceSerialNumber << QLatin1String("shell") << QLatin1String("ps")); if (!psProc.waitForFinished(-1)) { @@ -148,7 +150,7 @@ void AndroidRunner::asyncStart() arguments << QLatin1String("-s") << m_deviceSerialNumber << QLatin1String("forward") << QString::fromLatin1("tcp%1").arg(m_remoteChannel) << QString::fromLatin1("localfilesystem:/data/data/%1/debug-socket").arg(m_packageName); - adbStarProc.start(AndroidConfigurations::instance().adbToolPath(), arguments); + adbStarProc.start(AndroidConfigurations::instance().adbToolPath().toString(), arguments); if (!adbStarProc.waitForStarted()) { emit remoteProcessFinished(tr("Failed to forward debugging ports. Reason: $1").arg(adbStarProc.errorString())); return; @@ -176,7 +178,7 @@ void AndroidRunner::asyncStart() if (extraParams.length()) arguments << extraParams.split(QLatin1Char(' ')); - adbStarProc.start(AndroidConfigurations::instance().adbToolPath(), arguments); + adbStarProc.start(AndroidConfigurations::instance().adbToolPath().toString(), arguments); if (!adbStarProc.waitForStarted()) { emit remoteProcessFinished(tr("Failed to start the activity. Reason: $1").arg(adbStarProc.errorString())); return; @@ -209,7 +211,7 @@ void AndroidRunner::asyncStart() void AndroidRunner::startLogcat() { m_checkPIDTimer.start(1000); // check if the application is alive every 1 seconds - m_adbLogcatProcess.start(AndroidConfigurations::instance().adbToolPath(), + m_adbLogcatProcess.start(AndroidConfigurations::instance().adbToolPath().toString(), QStringList() << QLatin1String("-s") << m_deviceSerialNumber << QLatin1String("logcat")); emit remoteProcessStarted(5039); @@ -267,7 +269,7 @@ void AndroidRunner::adbKill(qint64 pid, const QString &device, int timeout, cons arguments << QLatin1String("kill") << QLatin1String("-9"); arguments << QString::number(pid); - process.start(AndroidConfigurations::instance().adbToolPath(), arguments); + process.start(AndroidConfigurations::instance().adbToolPath().toString(), arguments); if (!process.waitForFinished(timeout)) process.terminate(); } diff --git a/src/plugins/android/androidsettingswidget.cpp b/src/plugins/android/androidsettingswidget.cpp index 48fa82af5e9..0c9b86338d1 100644 --- a/src/plugins/android/androidsettingswidget.cpp +++ b/src/plugins/android/androidsettingswidget.cpp @@ -149,19 +149,19 @@ void AndroidSettingsWidget::initGui() m_ui->setupUi(this); m_ui->toolchainVersionComboBox->clear(); if (checkSDK(m_androidConfig.sdkLocation)) - m_ui->SDKLocationLineEdit->setText(m_androidConfig.sdkLocation); + m_ui->SDKLocationLineEdit->setText(m_androidConfig.sdkLocation.toUserOutput()); else m_androidConfig.sdkLocation.clear(); if (checkNDK(m_androidConfig.ndkLocation)) - m_ui->NDKLocationLineEdit->setText(m_androidConfig.ndkLocation); + m_ui->NDKLocationLineEdit->setText(m_androidConfig.ndkLocation.toUserOutput()); else m_androidConfig.ndkLocation.clear(); - m_ui->AntLocationLineEdit->setText(m_androidConfig.antLocation); - m_ui->GdbLocationLineEdit->setText(m_androidConfig.armGdbLocation); - m_ui->GdbserverLocationLineEdit->setText(m_androidConfig.armGdbserverLocation); - m_ui->GdbLocationLineEditx86->setText(m_androidConfig.x86GdbLocation); - m_ui->GdbserverLocationLineEditx86->setText(m_androidConfig.x86GdbserverLocation); - m_ui->OpenJDKLocationLineEdit->setText(m_androidConfig.openJDKLocation); + m_ui->AntLocationLineEdit->setText(m_androidConfig.antLocation.toUserOutput()); + m_ui->GdbLocationLineEdit->setText(m_androidConfig.armGdbLocation.toUserOutput()); + m_ui->GdbserverLocationLineEdit->setText(m_androidConfig.armGdbserverLocation.toUserOutput()); + m_ui->GdbLocationLineEditx86->setText(m_androidConfig.x86GdbLocation.toUserOutput()); + m_ui->GdbserverLocationLineEditx86->setText(m_androidConfig.x86GdbserverLocation.toUserOutput()); + m_ui->OpenJDKLocationLineEdit->setText(m_androidConfig.openJDKLocation.toUserOutput()); m_ui->DataPartitionSizeSpinBox->setValue(m_androidConfig.partitionSize); m_ui->AVDTableView->setModel(&m_AVDModel); m_AVDModel.setAvdList(AndroidConfigurations::instance().androidVirtualDevices()); @@ -181,33 +181,40 @@ void AndroidSettingsWidget::saveSettings(bool saveNow) } -bool AndroidSettingsWidget::checkSDK(const QString &location) +bool AndroidSettingsWidget::checkSDK(const Utils::FileName &location) { - if (!location.length()) + if (location.isEmpty()) return false; - if (!QFile::exists(location + QLatin1String("/platform-tools/adb" ANDROID_EXE_SUFFIX)) - || (!QFile::exists(location + QLatin1String("/tools/android" ANDROID_EXE_SUFFIX)) - && !QFile::exists(location + QLatin1String("/tools/android" ANDROID_BAT_SUFFIX))) - || !QFile::exists(location + QLatin1String("/tools/emulator" ANDROID_EXE_SUFFIX))) { - QMessageBox::critical(this, tr("Android SDK Folder"), tr("\"%1\" doesn't seem to be an Android SDK top folder").arg(location)); + Utils::FileName adb = location; + Utils::FileName androidExe = location; + Utils::FileName androidBat = location; + Utils::FileName emulator = location; + if (!adb.appendPath(QLatin1String("platform-tools/adb" ANDROID_EXE_SUFFIX)).toFileInfo().exists() + || (!androidExe.appendPath(QLatin1String("/tools/android" ANDROID_EXE_SUFFIX)).toFileInfo().exists() + && !androidBat.appendPath(QLatin1String("/tools/android" ANDROID_BAT_SUFFIX)).toFileInfo().exists()) + || !emulator.appendPath(QLatin1String("/tools/emulator" ANDROID_EXE_SUFFIX)).toFileInfo().exists()) { + QMessageBox::critical(this, tr("Android SDK Folder"), tr("\"%1\" doesn't seem to be an Android SDK top folder").arg(location.toUserOutput())); return false; } return true; } -bool AndroidSettingsWidget::checkNDK(const QString &location) +bool AndroidSettingsWidget::checkNDK(const Utils::FileName &location) { m_ui->toolchainVersionComboBox->setEnabled(false); m_ui->GdbLocationLineEdit->setEnabled(false); m_ui->GdbLocationPushButton->setEnabled(false); m_ui->GdbserverLocationLineEdit->setEnabled(false); m_ui->GdbserverLocationPushButton->setEnabled(false); - if (!location.length()) + if (location.isEmpty()) return false; - if (!QFile::exists(location + QLatin1String("/platforms")) - || !QFile::exists(location + QLatin1String("/toolchains")) - || !QFile::exists(location + QLatin1String("/sources/cxx-stl"))) { - QMessageBox::critical(this, tr("Android SDK Folder"), tr("\"%1\" doesn't seem to be an Android NDK top folder").arg(location)); + Utils::FileName platformPath = location; + Utils::FileName toolChainPath = location; + Utils::FileName sourcesPath = location; + if (!platformPath.appendPath(QLatin1String("platforms")).toFileInfo().exists() + || !toolChainPath.appendPath(QLatin1String("toolchains")).toFileInfo().exists() + || !sourcesPath.appendPath(QLatin1String("sources/cxx-stl")).toFileInfo().exists()) { + QMessageBox::critical(this, tr("Android SDK Folder"), tr("\"%1\" doesn't seem to be an Android NDK top folder").arg(location.toUserOutput())); return false; } m_ui->toolchainVersionComboBox->setEnabled(true); @@ -222,7 +229,7 @@ bool AndroidSettingsWidget::checkNDK(const QString &location) void AndroidSettingsWidget::sdkLocationEditingFinished() { - QString location = m_ui->SDKLocationLineEdit->text(); + Utils::FileName location = Utils::FileName::fromUserInput(m_ui->SDKLocationLineEdit->text()); if (!checkSDK(location)) { m_ui->AVDManagerFrame->setEnabled(false); return; @@ -235,8 +242,8 @@ void AndroidSettingsWidget::sdkLocationEditingFinished() void AndroidSettingsWidget::ndkLocationEditingFinished() { - QString location = m_ui->NDKLocationLineEdit->text(); - if (!checkNDK(location)) + Utils::FileName location = Utils::FileName::fromUserInput(m_ui->NDKLocationLineEdit->text()); + if (checkNDK(location)) return; m_androidConfig.ndkLocation = location; saveSettings(true); @@ -264,67 +271,67 @@ void AndroidSettingsWidget::toolchainVersionIndexChanged(QString version) void AndroidSettingsWidget::antLocationEditingFinished() { - QString location = m_ui->AntLocationLineEdit->text(); - if (!location.length() || !QFile::exists(location)) + Utils::FileName location = Utils::FileName::fromUserInput(m_ui->AntLocationLineEdit->text()); + if (location.isEmpty() || !location.toFileInfo().exists()) return; m_androidConfig.antLocation = location; } void AndroidSettingsWidget::gdbLocationEditingFinished() { - QString location = m_ui->GdbLocationLineEdit->text(); - if (!location.length() || !QFile::exists(location)) + Utils::FileName location = Utils::FileName::fromUserInput(m_ui->GdbLocationLineEdit->text()); + if (location.isEmpty() || !location.toFileInfo().exists()) return; m_androidConfig.armGdbLocation = location; } void AndroidSettingsWidget::gdbserverLocationEditingFinished() { - QString location = m_ui->GdbserverLocationLineEdit->text(); - if (!location.length() || !QFile::exists(location)) + Utils::FileName location = Utils::FileName::fromUserInput(m_ui->GdbserverLocationLineEdit->text()); + if (location.isEmpty() || !location.toFileInfo().exists()) return; m_androidConfig.armGdbserverLocation = location; } void AndroidSettingsWidget::gdbLocationX86EditingFinished() { - QString location = m_ui->GdbLocationLineEditx86->text(); - if (!location.length() || !QFile::exists(location)) + Utils::FileName location = Utils::FileName::fromUserInput(m_ui->GdbLocationLineEditx86->text()); + if (location.isEmpty() || !location.toFileInfo().exists()) return; m_androidConfig.x86GdbLocation = location; } void AndroidSettingsWidget::gdbserverLocationX86EditingFinished() { - QString location = m_ui->GdbserverLocationLineEditx86->text(); - if (!location.length() || !QFile::exists(location)) + Utils::FileName location = Utils::FileName::fromUserInput(m_ui->GdbserverLocationLineEditx86->text()); + if (location.isEmpty() || !location.toFileInfo().exists()) return; m_androidConfig.x86GdbserverLocation = location; } void AndroidSettingsWidget::openJDKLocationEditingFinished() { - QString location = m_ui->OpenJDKLocationLineEdit->text(); - if (!location.length() || !QFile::exists(location)) + Utils::FileName location = Utils::FileName::fromUserInput(m_ui->OpenJDKLocationLineEdit->text()); + if (location.isEmpty() || !location.toFileInfo().exists()) return; m_androidConfig.openJDKLocation = location; } void AndroidSettingsWidget::browseSDKLocation() { - QString dir = QFileDialog::getExistingDirectory(this, tr("Select Android SDK Folder")); + Utils::FileName dir = Utils::FileName::fromString(QFileDialog::getExistingDirectory(this, tr("Select Android SDK folder"))); if (!checkSDK(dir)) return; - m_ui->SDKLocationLineEdit->setText(dir); + m_ui->SDKLocationLineEdit->setText(dir.toUserOutput()); sdkLocationEditingFinished(); } void AndroidSettingsWidget::browseNDKLocation() { - QString dir = QFileDialog::getExistingDirectory(this, tr("Select Android NDK Folder")); + Utils::FileName dir = Utils::FileName::fromString(QFileDialog::getExistingDirectory(this, tr("Select Android NDK folder"))); if (!checkNDK(dir)) return; - m_ui->NDKLocationLineEdit->setText(dir); + m_ui->NDKLocationLineEdit->setText(dir.toUserOutput()); ndkLocationEditingFinished(); } @@ -350,55 +357,51 @@ void AndroidSettingsWidget::browseAntLocation() void AndroidSettingsWidget::browseGdbLocation() { - QString gdbPath = AndroidConfigurations::instance().gdbPath(ProjectExplorer::Abi::ArmArchitecture); - QString file = QFileDialog::getOpenFileName(this, tr("Select gdb Executable"),gdbPath); - if (!file.length()) + Utils::FileName gdbPath = AndroidConfigurations::instance().gdbPath(ProjectExplorer::Abi::ArmArchitecture); + Utils::FileName file = Utils::FileName::fromString(QFileDialog::getOpenFileName(this, tr("Select gdb executable"), gdbPath.toString())); + if (file.isEmpty()) return; - m_ui->GdbLocationLineEdit->setText(file); + m_ui->GdbLocationLineEdit->setText(file.toUserOutput()); gdbLocationEditingFinished(); } void AndroidSettingsWidget::browseGdbserverLocation() { - QString gdbserverPath = AndroidConfigurations::instance().gdbServerPath(ProjectExplorer::Abi::ArmArchitecture); - const QString file = - QFileDialog::getOpenFileName(this, tr("Select gdbserver Android Executable"),gdbserverPath); - if (!file.length()) + Utils::FileName gdbserverPath = AndroidConfigurations::instance().gdbServerPath(ProjectExplorer::Abi::ArmArchitecture); + Utils::FileName file = Utils::FileName::fromString(QFileDialog::getOpenFileName(this, tr("Select gdbserver android executable"), gdbserverPath.toString())); + if (file.isEmpty()) return; - m_ui->GdbserverLocationLineEdit->setText(file); + m_ui->GdbserverLocationLineEdit->setText(file.toUserOutput()); gdbserverLocationEditingFinished(); } void AndroidSettingsWidget::browseGdbLocationX86() { - QString gdbPath = AndroidConfigurations::instance().gdbPath(ProjectExplorer::Abi::X86Architecture); - const QString file = - QFileDialog::getOpenFileName(this, tr("Select gdb Executable"),gdbPath); - if (!file.length()) + Utils::FileName gdbPath = AndroidConfigurations::instance().gdbPath(ProjectExplorer::Abi::X86Architecture); + Utils::FileName file = Utils::FileName::fromString(QFileDialog::getOpenFileName(this, tr("Select gdb executable"), gdbPath.toString())); + if (file.isEmpty()) return; - m_ui->GdbLocationLineEditx86->setText(file); + m_ui->GdbLocationLineEditx86->setText(file.toUserOutput()); gdbLocationX86EditingFinished(); } void AndroidSettingsWidget::browseGdbserverLocationX86() { - QString gdbserverPath = AndroidConfigurations::instance().gdbServerPath(ProjectExplorer::Abi::X86Architecture); - const QString file = - QFileDialog::getOpenFileName(this, tr("Select gdbserver Android Executable"), gdbserverPath); - if (!file.length()) + Utils::FileName gdbserverPath = AndroidConfigurations::instance().gdbServerPath(ProjectExplorer::Abi::X86Architecture); + Utils::FileName file = Utils::FileName::fromString(QFileDialog::getOpenFileName(this, tr("Select gdbserver android executable"), gdbserverPath.toString())); + if (file.isEmpty()) return; - m_ui->GdbserverLocationLineEditx86->setText(file); + m_ui->GdbserverLocationLineEditx86->setText(file.toUserOutput()); gdbserverLocationX86EditingFinished(); } void AndroidSettingsWidget::browseOpenJDKLocation() { - QString openJDKPath = AndroidConfigurations::instance().openJDKPath(); - const QString file = - QFileDialog::getOpenFileName(this, tr("Select OpenJDK Path"), openJDKPath); - if (!file.length()) + Utils::FileName openJDKPath = AndroidConfigurations::instance().openJDKPath(); + Utils::FileName file = Utils::FileName::fromString(QFileDialog::getOpenFileName(this, tr("Select OpenJDK path"), openJDKPath.toString())); + if (file.isEmpty()) return; - m_ui->OpenJDKLocationLineEdit->setText(file); + m_ui->OpenJDKLocationLineEdit->setText(file.toUserOutput()); openJDKLocationEditingFinished(); } @@ -436,7 +439,8 @@ void AndroidSettingsWidget::manageAVD() QProcess *avdProcess = new QProcess(); connect(this, SIGNAL(destroyed()), avdProcess, SLOT(deleteLater())); connect(avdProcess, SIGNAL(finished(int)), avdProcess, SLOT(deleteLater())); - avdProcess->start(AndroidConfigurations::instance().androidToolPath(), QStringList() << QLatin1String("avd")); + avdProcess->start(AndroidConfigurations::instance().androidToolPath().toString(), + QStringList() << QLatin1String("avd")); } diff --git a/src/plugins/android/androidsettingswidget.h b/src/plugins/android/androidsettingswidget.h index fa985a6cb74..8de720593d5 100644 --- a/src/plugins/android/androidsettingswidget.h +++ b/src/plugins/android/androidsettingswidget.h @@ -72,6 +72,7 @@ class AndroidSettingsWidget : public QWidget { Q_OBJECT public: + // Todo: This would be so much simpler if it just used Utils::PathChooser!!! AndroidSettingsWidget(QWidget *parent); ~AndroidSettingsWidget(); @@ -105,8 +106,8 @@ private slots: private: void initGui(); - bool checkSDK(const QString &location); - bool checkNDK(const QString &location); + bool checkSDK(const Utils::FileName &location); + bool checkNDK(const Utils::FileName &location); void fillToolchainVersions(); Ui_AndroidSettingsWidget *m_ui; diff --git a/src/plugins/android/androidtarget.h b/src/plugins/android/androidtarget.h deleted file mode 100644 index dbbd13273d2..00000000000 --- a/src/plugins/android/androidtarget.h +++ /dev/null @@ -1,204 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2012 BogDan Vatra <[email protected]> -** -** Contact: Nokia Corporation ([email protected]) -** -** -** GNU Lesser General Public License Usage -** -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** Other Usage -** -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** If you have questions regarding the use of this file, please contact -** Nokia at [email protected]. -** -**************************************************************************/ - -#ifndef ANDROIDTEMPLATESCREATOR_H -#define ANDROIDTEMPLATESCREATOR_H - -#include "qt4projectmanager/qt4target.h" -#include "qt4projectmanager/qt4buildconfiguration.h" - -#include <QMap> -#include <QIcon> -#include <QDomDocument> - -QT_FORWARD_DECLARE_CLASS(QFileSystemWatcher); - -namespace ProjectExplorer { -class Project; -class ProjectNode; -class Target; -} - -namespace Qt4ProjectManager { -class Qt4Project; -class Qt4Target; -class Qt4ProFileNode; -} - - -namespace Android { -namespace Internal { -class AndroidTargetFactory; - -class AndroidTarget : public Qt4ProjectManager::Qt4BaseTarget -{ - friend class AndroidTargetFactory; - Q_OBJECT - enum AndroidIconType - { - HighDPI, - MediumDPI, - LowDPI - }; - - struct Library - { - Library() - { - level = -1; - } - int level; - QStringList dependencies; - QString name; - }; - typedef QMap<QString, Library> LibrariesMap; -public: - enum BuildType - { - DebugBuild, - ReleaseBuildUnsigned, - ReleaseBuildSigned - }; - - explicit AndroidTarget(Qt4ProjectManager::Qt4Project *parent, const Core::Id id); - virtual ~AndroidTarget(); - - Qt4ProjectManager::Qt4BuildConfigurationFactory *buildConfigurationFactory() const; - - void createApplicationProFiles(bool reparse); - - QList<ProjectExplorer::RunConfiguration *> runConfigurationsForNode(ProjectExplorer::Node *n); - - static QString defaultDisplayName(); - - - QString packageName() const; - bool setPackageName(const QString &name) const; - - QString intentName() const; - QString activityName() const; - - QString applicationName() const; - bool setApplicationName(const QString &name) const; - - QStringList availableTargetApplications() const; - QString targetApplication() const; - bool setTargetApplication(const QString &name) const; - QString targetApplicationPath() const; - - QString targetSDK() const; - bool setTargetSDK(const QString &target) const; - - int versionCode() const; - bool setVersionCode(int version) const; - - QString versionName() const; - bool setVersionName(const QString &version) const; - - QStringList permissions() const; - bool setPermissions(const QStringList &permissions) const; - - QStringList availableQtLibs() const; - QStringList qtLibs() const; - bool setQtLibs(const QStringList &qtLibs) const; - - QStringList availablePrebundledLibs() const; - QStringList prebundledLibs() const; - bool setPrebundledLibs(const QStringList &qtLibs) const; - - QIcon highDpiIcon() const; - bool setHighDpiIcon(const QString &iconFilePath) const; - - QIcon mediumDpiIcon() const; - bool setMediumDpiIcon(const QString &iconFilePath) const; - - QIcon lowDpiIcon() const; - bool setLowDpiIcon(const QString &iconFilePath) const; - - QString androidDirPath() const; - QString androidManifestPath() const; - QString androidLibsPath() const; - QString androidStringsPath() const; - QString androidDefaultPropertiesPath() const; - QString androidSrcPath() const; - QString apkPath(BuildType buildType) const; - QString localLibsRulesFilePath() const; - QString loadLocalLibs(int apiLevel) const; - QString loadLocalJars(int apiLevel) const; - -public slots: - bool createAndroidTemplatesIfNecessary() const; - void updateProject(const QString &targetSDK, const QString &name = QString()) const; - -signals: - void androidDirContentsChanged(); - -private slots: - void handleTargetChanged(ProjectExplorer::Target *target); - void handleTargetToBeRemoved(ProjectExplorer::Target *target); - -private: - enum ItemType - { - Lib, - Jar - }; - - QString loadLocal(int apiLevel, ItemType item) const; - void raiseError(const QString &reason) const; - bool openXmlFile(QDomDocument &doc, const QString &fileName, bool createAndroidTemplates = true) const; - bool saveXmlFile(QDomDocument &doc, const QString &fileName) const; - bool openAndroidManifest(QDomDocument &doc) const; - bool saveAndroidManifest(QDomDocument &doc) const; - bool openLibsXml(QDomDocument &doc) const; - bool saveLibsXml(QDomDocument &doc) const; - - QIcon androidIcon(AndroidIconType type) const; - bool setAndroidIcon(AndroidIconType type, const QString &iconFileName) const; - - QStringList libsXml(const QString &tag) const; - bool setLibsXml(const QStringList &qtLibs, const QString &tag) const; - - static bool qtLibrariesLessThan(const AndroidTarget::Library &a, const AndroidTarget::Library &b); - QStringList getDependencies(const QString &readelfPath, const QString &lib) const; - int setLibraryLevel(const QString &library, LibrariesMap &mapLibs) const; - - - QFileSystemWatcher *const m_androidFilesWatcher; - - Qt4ProjectManager::Qt4BuildConfigurationFactory *m_buildConfigurationFactory; -}; - -} // namespace Internal -} // namespace Android - -#endif // ANDROIDTEMPLATESCREATOR_H diff --git a/src/plugins/android/androidtargetfactory.cpp b/src/plugins/android/androidtargetfactory.cpp deleted file mode 100644 index 180aa851ba5..00000000000 --- a/src/plugins/android/androidtargetfactory.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2012 BogDan Vatra <[email protected]> -** -** Contact: Nokia Corporation ([email protected]) -** -** -** GNU Lesser General Public License Usage -** -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** Other Usage -** -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** If you have questions regarding the use of this file, please contact -** Nokia at [email protected]. -** -**************************************************************************/ - -#include "androidtargetfactory.h" -#include "qt4projectmanager/qt4project.h" -#include "qt4projectmanager/qt4projectmanagerconstants.h" -#include "androiddeploystep.h" -#include "androidglobal.h" -#include "androidpackagecreationstep.h" -#include "androidrunconfiguration.h" -#include "androidtarget.h" -#include "androiddeployconfiguration.h" - -#include <projectexplorer/deployconfiguration.h> -#include <projectexplorer/projectexplorerconstants.h> -#include <qt4projectmanager/buildconfigurationinfo.h> -#include <qtsupport/customexecutablerunconfiguration.h> - -#include <qtsupport/qtversionmanager.h> - -using namespace Qt4ProjectManager; -using namespace Android::Internal; -using ProjectExplorer::idFromMap; - -// ------------------------------------------------------------------------- -// Qt4AndroidTargetFactory -// ------------------------------------------------------------------------- -AndroidTargetFactory::AndroidTargetFactory(QObject *parent) : - Qt4BaseTargetFactory(parent) -{ - connect(QtSupport::QtVersionManager::instance(), SIGNAL(qtVersionsChanged(QList<int>,QList<int>,QList<int>)), - this, SIGNAL(canCreateTargetIdsChanged())); -} - -AndroidTargetFactory::~AndroidTargetFactory() -{ -} - -bool AndroidTargetFactory::supportsTargetId(const Core::Id id) const -{ - return id == Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID); -} - -QSet<QString> AndroidTargetFactory::targetFeatures(const Core::Id id) const -{ - Q_UNUSED(id); - QSet<QString> features; - features << QLatin1String(Qt4ProjectManager::Constants::MOBILE_TARGETFEATURE_ID); - features << QLatin1String(Qt4ProjectManager::Constants::SHADOWBUILD_TARGETFEATURE_ID); - return features; -} - -QList<Core::Id> AndroidTargetFactory::supportedTargetIds() const -{ - return QList<Core::Id>() << Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID); -} - -QString AndroidTargetFactory::displayNameForId(const Core::Id id) const -{ - if (id == Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID)) - return AndroidTarget::defaultDisplayName(); - return QString(); -} - -QIcon AndroidTargetFactory::iconForId(const Core::Id id) const -{ - Q_UNUSED(id) - return QIcon(QLatin1String(Constants::ANDROID_SETTINGS_CATEGORY_ICON)); -} - -bool AndroidTargetFactory::canCreate(ProjectExplorer::Project *parent, const Core::Id id) const -{ - if (!qobject_cast<Qt4Project *>(parent)) - return false; - if (!supportsTargetId(id)) - return false; - return QtSupport::QtVersionManager::instance()->supportsTargetId(id); -} - -bool AndroidTargetFactory::canRestore(ProjectExplorer::Project *parent, const QVariantMap &map) const -{ - return canCreate(parent, idFromMap(map)); -} - -Qt4BaseTarget *AndroidTargetFactory::restore(ProjectExplorer::Project *parent, const QVariantMap &map) -{ - if (!canRestore(parent, map)) - return 0; - - const Core::Id id = idFromMap(map); - AndroidTarget *target = 0; - Qt4Project *qt4project = static_cast<Qt4Project *>(parent); - if (id == Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID)) - target = new AndroidTarget(qt4project, id); - if (target && target->fromMap(map)) - return target; - delete target; - return 0; -} - -Qt4BaseTarget *AndroidTargetFactory::create(ProjectExplorer::Project *parent, const Core::Id id) -{ - if (!canCreate(parent, id)) - return 0; - - QList<QtSupport::BaseQtVersion *> knownVersions = QtSupport::QtVersionManager::instance()->versionsForTargetId(id); - if (knownVersions.isEmpty()) - return 0; - - QtSupport::BaseQtVersion *qtVersion = knownVersions.first(); - bool buildAll = qtVersion->isValid() && (qtVersion->defaultBuildConfig() & QtSupport::BaseQtVersion::BuildAll); - QtSupport::BaseQtVersion::QmakeBuildConfigs config = buildAll ? QtSupport::BaseQtVersion::BuildAll : QtSupport::BaseQtVersion::QmakeBuildConfig(0); - - QList<Qt4ProjectManager::BuildConfigurationInfo> infos; - infos.append(Qt4ProjectManager::BuildConfigurationInfo(qtVersion->uniqueId(), config, QString(), QString())); - infos.append(Qt4ProjectManager::BuildConfigurationInfo(qtVersion->uniqueId(), config ^ QtSupport::BaseQtVersion::DebugBuild, QString(), QString())); - - return create(parent, id, infos); -} - -Qt4BaseTarget *AndroidTargetFactory::create(ProjectExplorer::Project *parent, const Core::Id id, - const QList<Qt4ProjectManager::BuildConfigurationInfo> &infos) -{ - if (!canCreate(parent, id)) - return 0; - - AndroidTarget *target = 0; - if (id == Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID)) - target = new AndroidTarget(static_cast<Qt4Project *>(parent), id); - Q_ASSERT(target); - - foreach (const Qt4ProjectManager::BuildConfigurationInfo &info, infos) { - QString displayName = info.version()->displayName() + QLatin1Char(' '); - displayName += (info.buildConfig & QtSupport::BaseQtVersion::DebugBuild) ? tr("Debug") : tr("Release"); - target->addQt4BuildConfiguration(displayName, QString(), - info.version(), - info.buildConfig, - info.additionalArguments, - info.directory, - info.importing); - } - - target->addDeployConfiguration(target->createDeployConfiguration(Core::Id(ANDROID_DEPLOYCONFIGURATION_ID))); - - target->createApplicationProFiles(false); - if (target->runConfigurations().isEmpty()) - target->addRunConfiguration(new QtSupport::CustomExecutableRunConfiguration(target)); - return target; -} - -QString AndroidTargetFactory::buildNameForId(const Core::Id id) const -{ - if (id == Core::Id(Qt4ProjectManager::Constants::ANDROID_DEVICE_TARGET_ID)) - return QLatin1String("android"); - return QString(); -} diff --git a/src/plugins/android/androidtargetfactory.h b/src/plugins/android/androidtargetfactory.h deleted file mode 100644 index c0f77f390d2..00000000000 --- a/src/plugins/android/androidtargetfactory.h +++ /dev/null @@ -1,70 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2012 BogDan Vatra <[email protected]> -** -** Contact: Nokia Corporation ([email protected]) -** -** -** GNU Lesser General Public License Usage -** -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** Other Usage -** -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** If you have questions regarding the use of this file, please contact -** Nokia at [email protected]. -** -**************************************************************************/ - -#ifndef QT4ANDROIDTARGETFACTORY_H -#define QT4ANDROIDTARGETFACTORY_H - -#include "qt4projectmanager/qt4basetargetfactory.h" -#include "qt4projectmanager/qt4target.h" - -namespace Android { -namespace Internal { - -class AndroidTargetFactory : public Qt4ProjectManager::Qt4BaseTargetFactory -{ - Q_OBJECT -public: - AndroidTargetFactory(QObject *parent = 0); - ~AndroidTargetFactory(); - - QList<Core::Id> supportedTargetIds() const; - QString displayNameForId(const Core::Id id) const; - QIcon iconForId(const Core::Id id) const; - - bool canCreate(ProjectExplorer::Project *parent, const Core::Id id) const; - bool canRestore(ProjectExplorer::Project *parent, const QVariantMap &map) const; - Qt4ProjectManager::Qt4BaseTarget *restore(ProjectExplorer::Project *parent, const QVariantMap &map); - - bool supportsTargetId(const Core::Id id) const; - virtual QSet<QString> targetFeatures(const Core::Id id) const; - - Qt4ProjectManager::Qt4BaseTarget *create(ProjectExplorer::Project *parent, const Core::Id id); - Qt4ProjectManager::Qt4BaseTarget *create(ProjectExplorer::Project *parent, const Core::Id id, - const QList<Qt4ProjectManager::BuildConfigurationInfo> &infos); - - QString buildNameForId(const Core::Id id) const; -}; - -} // namespace Internal -} // namespace Android - -#endif // QT4ANDROIDTARGETFACTORY_H diff --git a/src/plugins/android/androidtoolchain.cpp b/src/plugins/android/androidtoolchain.cpp index 1c6c9c1a3a0..d9955c805bc 100644 --- a/src/plugins/android/androidtoolchain.cpp +++ b/src/plugins/android/androidtoolchain.cpp @@ -33,7 +33,7 @@ #include "androidtoolchain.h" #include "androidconstants.h" #include "androidconfigurations.h" -#include "androidtarget.h" +#include "androidmanager.h" #include "androidqtversion.h" #include "qt4projectmanager/qt4projectmanagerconstants.h" @@ -103,21 +103,17 @@ void AndroidToolChain::addToEnvironment(Utils::Environment &env) const // this env vars are used by qmake mkspecs to generate makefiles (check QTDIR/mkspecs/android-g++/qmake.conf for more info) env.set(QLatin1String("ANDROID_NDK_HOST"), ndk_host); - env.set(QLatin1String("ANDROID_NDK_ROOT"), - QDir::toNativeSeparators(AndroidConfigurations::instance().config().ndkLocation)); + env.set(QLatin1String("ANDROID_NDK_ROOT"), AndroidConfigurations::instance().config().ndkLocation.toUserOutput()); env.set(QLatin1String("ANDROID_NDK_TOOLCHAIN_PREFIX"), AndroidConfigurations::toolchainPrefix(targetAbi().architecture())); env.set(QLatin1String("ANDROID_NDK_TOOLS_PREFIX"), AndroidConfigurations::toolsPrefix(targetAbi().architecture())); env.set(QLatin1String("ANDROID_NDK_TOOLCHAIN_VERSION"), AndroidConfigurations::instance().config().ndkToolchainVersion); // TODO that is very ugly and likely to be wrong... Qt4Project *qt4pro = qobject_cast<Qt4Project *>(ProjectExplorer::ProjectExplorerPlugin::instance()->currentProject()); - if (!qt4pro) - return; - AndroidTarget *at = qobject_cast<AndroidTarget *>(qt4pro->activeTarget()); - if (!at) + if (!qt4pro || !qt4pro->activeTarget()) return; env.set(QLatin1String("ANDROID_NDK_PLATFORM"), - AndroidConfigurations::instance().bestMatch(at->targetSDK())); + AndroidConfigurations::instance().bestMatch(AndroidManager::targetSDK(qt4pro->activeTarget()))); } bool AndroidToolChain::operator ==(const ProjectExplorer::ToolChain &tc) const @@ -202,11 +198,6 @@ QList<ProjectExplorer::Abi> AndroidToolChain::detectSupportedAbis() const return aqv->qtAbis(); } -QString AndroidToolChain::legacyId() const -{ - return QString::fromLatin1("%1:%2").arg(QLatin1String(Constants::ANDROID_TOOLCHAIN_ID)).arg(m_qtVersionId); -} - // -------------------------------------------------------------------------- // ToolChainConfigWidget // -------------------------------------------------------------------------- @@ -218,7 +209,7 @@ AndroidToolChainConfigWidget::AndroidToolChainConfigWidget(AndroidToolChain *tc) QLabel *label = new QLabel; QtSupport::BaseQtVersion *v = QtSupport::QtVersionManager::instance()->version(tc->qtVersionId()); Q_ASSERT(v); - label->setText(tr("NDK Root: %1").arg(AndroidConfigurations::instance().config().ndkLocation)); + label->setText(tr("NDK Root: %1").arg(AndroidConfigurations::instance().config().ndkLocation.toUserOutput())); layout->addWidget(label); } @@ -323,7 +314,7 @@ QList<ProjectExplorer::ToolChain *> AndroidToolChainFactory::createToolChainList aTc->setDisplayName(tr("Android GCC (%1-%2)") .arg(ProjectExplorer::Abi::toString(aTc->targetAbi().architecture())) .arg(AndroidConfigurations::instance().config().ndkToolchainVersion)); - aTc->setCompilerCommand(Utils::FileName::fromString(AndroidConfigurations::instance().gccPath(aTc->targetAbi().architecture()))); + aTc->setCompilerCommand(AndroidConfigurations::instance().gccPath(aTc->targetAbi().architecture())); result.append(aTc); } return result; diff --git a/src/plugins/android/androidtoolchain.h b/src/plugins/android/androidtoolchain.h index e38cbaf9c55..7563a2e6afa 100644 --- a/src/plugins/android/androidtoolchain.h +++ b/src/plugins/android/androidtoolchain.h @@ -67,7 +67,7 @@ public: void setQtVersionId(int); int qtVersionId() const; - QString legacyId() const; + protected: virtual QList<ProjectExplorer::Abi> detectSupportedAbis() const; |