From 9e057a55368286058023510efc328f68250ecb5e Mon Sep 17 00:00:00 2001 From: Assam Boudjelthia Date: Thu, 16 Apr 2020 16:44:06 +0300 Subject: [PATCH] Android: add support for new SDK Tools package cmdline-tools The newly added cmdline-tools is not used by Qt Creator. So QC Android settings will be broken for users who have an Android SDK installed from Android Studio, or who updated their SDK package (i.e. tools -> cmdline-tools). This patch fixes both of the following issues: 1- QC looks for sdkmanager tools under /tools/bin/sdkmanager, and with the new SDK it's under /cmdline-tools/latest/sdkmanger. 2- QC checks the version of the SDK tools and opens the old SDK Manager for SDK tools version 25.3.0 or less. However, since cmdline-tools is now version 1.0, it causes QC to think this is an old version. Fixes: QTCREATORBUG-23726 Change-Id: I7e6bbc6840d24d358f68dfa3e229799394ace950 Reviewed-by: BogDan Vatra --- src/plugins/android/androidbuildapkstep.cpp | 3 +- src/plugins/android/androidconfigurations.cpp | 55 ++++++++++++++----- src/plugins/android/androidconfigurations.h | 1 + src/plugins/android/androidsdkmanager.cpp | 10 +++- 4 files changed, 53 insertions(+), 16 deletions(-) diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index 5f31ca86207..94cb986b19c 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -172,7 +172,8 @@ bool AndroidBuildApkStep::init() return false; const QVersionNumber sdkToolsVersion = AndroidConfigurations::currentConfig().sdkToolsVersion(); - if (sdkToolsVersion >= gradleScriptRevokedSdkVersion) { + if (sdkToolsVersion >= gradleScriptRevokedSdkVersion + || AndroidConfigurations::currentConfig().isCmdlineSdkToolsInstalled()) { if (!version->sourcePath().pathAppended("src/3rdparty/gradle").exists()) { emit addOutput(tr("The installed SDK tools version (%1) does not include Gradle " "scripts. The minimum Qt version required for Gradle build to work " diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index 14cf58f2f59..a574c4c1239 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -428,6 +428,15 @@ QString AndroidConfig::apiLevelNameFor(const SdkPlatform *platform) QString("android-%1").arg(platform->apiLevel()) : ""; } +bool AndroidConfig::isCmdlineSdkToolsInstalled() const +{ + QString toolPath("cmdline-tools/latest/bin/sdkmanager"); + if (HostOsInfo::isWindowsHost()) + toolPath += ANDROID_BAT_SUFFIX; + + return m_sdkLocation.pathAppended(toolPath).exists(); +} + FilePath AndroidConfig::adbToolPath() const { return m_sdkLocation.pathAppended("platform-tools/adb" QTC_HOST_EXE_SUFFIX); @@ -449,25 +458,43 @@ FilePath AndroidConfig::androidToolPath() const FilePath AndroidConfig::emulatorToolPath() const { QString relativePath = "emulator/emulator"; - if (sdkToolsVersion() < QVersionNumber(25, 3, 0)) + if (sdkToolsVersion() < QVersionNumber(25, 3, 0) && !isCmdlineSdkToolsInstalled()) relativePath = "tools/emulator"; return m_sdkLocation.pathAppended(relativePath + QTC_HOST_EXE_SUFFIX); } FilePath AndroidConfig::sdkManagerToolPath() const { - QString toolPath = "tools/bin/sdkmanager"; - if (HostOsInfo::isWindowsHost()) - toolPath += ANDROID_BAT_SUFFIX; - return m_sdkLocation.pathAppended(toolPath); + QStringList sdkmanagerPaths = {"cmdline-tools/latest/bin/sdkmanager", + "tools/bin/sdkmanager"}; + + for (QString &toolPath : sdkmanagerPaths) { + if (HostOsInfo::isWindowsHost()) + toolPath += ANDROID_BAT_SUFFIX; + + const FilePath sdkmanagerPath = m_sdkLocation.pathAppended(toolPath); + if (sdkmanagerPath.exists()) + return sdkmanagerPath; + } + + return FilePath(); } FilePath AndroidConfig::avdManagerToolPath() const { - QString toolPath = "tools/bin/avdmanager"; - if (HostOsInfo::isWindowsHost()) - toolPath += ANDROID_BAT_SUFFIX; - return m_sdkLocation.pathAppended(toolPath); + QStringList sdkmanagerPaths = {"cmdline-tools/latest/bin/avdmanager", + "tools/bin/avdmanager"}; + + for (QString &toolPath : sdkmanagerPaths) { + if (HostOsInfo::isWindowsHost()) + toolPath += ANDROID_BAT_SUFFIX; + + const FilePath sdkmanagerPath = m_sdkLocation.pathAppended(toolPath); + if (sdkmanagerPath.exists()) + return sdkmanagerPath; + } + + return FilePath(); } FilePath AndroidConfig::aaptToolPath() const @@ -812,7 +839,7 @@ QStringList AndroidConfig::getAbis(const FilePath &adbToolPath, const QString &d bool AndroidConfig::useNativeUiTools() const { const QVersionNumber version = sdkToolsVersion(); - return !version.isNull() && version <= QVersionNumber(25, 3 ,0); + return !version.isNull() && version <= QVersionNumber(25, 3, 0) && !isCmdlineSdkToolsInstalled(); } bool AndroidConfig::isValidNdk(const QString &ndkLocation) const @@ -849,8 +876,11 @@ QVersionNumber AndroidConfig::sdkToolsVersion() const { QVersionNumber version; if (m_sdkLocation.exists()) { - const Utils::FilePath sdkToolsPropertiesPath - = m_sdkLocation.pathAppended("tools/source.properties"); + FilePath sdkToolsPropertiesPath; + if (isCmdlineSdkToolsInstalled()) + sdkToolsPropertiesPath = m_sdkLocation.pathAppended("cmdline-tools/latest/source.properties"); + else + sdkToolsPropertiesPath = m_sdkLocation.pathAppended("tools/source.properties"); QSettings settings(sdkToolsPropertiesPath.toString(), QSettings::IniFormat); auto versionStr = settings.value(sdkToolsVersionKey).toString(); version = QVersionNumber::fromString(versionStr); @@ -868,7 +898,6 @@ QVersionNumber AndroidConfig::buildToolsVersion() const return maxVersion; } - QStringList AndroidConfig::sdkManagerToolArgs() const { return m_sdkManagerToolArgs; diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h index f10d86bf006..a6f6c5d4a2e 100644 --- a/src/plugins/android/androidconfigurations.h +++ b/src/plugins/android/androidconfigurations.h @@ -186,6 +186,7 @@ public: bool isConnected(const QString &serialNumber) const; bool useNativeUiTools() const; + bool isCmdlineSdkToolsInstalled() const; bool sdkFullyConfigured() const { return m_sdkFullyConfigured; } void setSdkFullyConfigured(bool allEssentialsInstalled) { m_sdkFullyConfigured = allEssentialsInstalled; } diff --git a/src/plugins/android/androidsdkmanager.cpp b/src/plugins/android/androidsdkmanager.cpp index e3ea6860890..3b58d81ad20 100644 --- a/src/plugins/android/androidsdkmanager.cpp +++ b/src/plugins/android/androidsdkmanager.cpp @@ -1,4 +1,4 @@ -/**************************************************************************** +/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ @@ -277,6 +277,7 @@ public: EmulatorToolsMarker = 0x400, NdkMarker = 0x800, ExtrasMarker = 0x1000, + CmdlineSdkToolsMarker = 0x2000, SectionMarkers = InstalledPackagesMarker | AvailablePackagesMarkers | AvailableUpdatesMarker }; @@ -313,6 +314,7 @@ const std::map markerTags { {SdkManagerOutputParser::MarkerTag::SystemImageMarker, "system-images"}, {SdkManagerOutputParser::MarkerTag::BuildToolsMarker, "build-tools"}, {SdkManagerOutputParser::MarkerTag::SdkToolsMarker, "tools"}, + {SdkManagerOutputParser::MarkerTag::CmdlineSdkToolsMarker, "cmdline-tools"}, {SdkManagerOutputParser::MarkerTag::PlatformToolsMarker, "platform-tools"}, {SdkManagerOutputParser::MarkerTag::EmulatorToolsMarker, "emulator"}, {SdkManagerOutputParser::MarkerTag::NdkMarker, "ndk"}, @@ -597,6 +599,10 @@ void SdkManagerOutputParser::parsePackageData(MarkerTag packageMarker, const QSt createPackage(&SdkManagerOutputParser::parseSdkToolsPackage); break; + case MarkerTag::CmdlineSdkToolsMarker: + createPackage(&SdkManagerOutputParser::parseSdkToolsPackage); + break; + case MarkerTag::PlatformToolsMarker: createPackage(&SdkManagerOutputParser::parsePlatformToolsPackage); break; @@ -882,7 +888,7 @@ void AndroidSdkManagerPrivate::reloadSdkPackages() return; } - if (m_config.sdkToolsVersion() < sdkManagerIntroVersion) { + if (m_config.sdkToolsVersion() < sdkManagerIntroVersion && !m_config.isCmdlineSdkToolsInstalled()) { // Old Sdk tools. m_packageListingSuccessful = true; AndroidToolManager toolManager(m_config);