| 
									
										
										
										
											2016-01-15 14:57:40 +01:00
										 |  |  | /****************************************************************************
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2016-01-15 14:57:40 +01:00
										 |  |  | ** Copyright (C) 2016 BogDan Vatra <bog_dan_ro@yahoo.com> | 
					
						
							|  |  |  | ** Contact: https://www.qt.io/licensing/
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** This file is part of Qt Creator. | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** Commercial License Usage | 
					
						
							|  |  |  | ** Licensees holding valid commercial Qt licenses may use this file in | 
					
						
							|  |  |  | ** accordance with the commercial license agreement provided with the | 
					
						
							|  |  |  | ** Software or, alternatively, in accordance with the terms contained in | 
					
						
							| 
									
										
										
										
											2016-01-15 14:57:40 +01:00
										 |  |  | ** a written agreement between you and The Qt Company. For licensing terms | 
					
						
							|  |  |  | ** and conditions see https://www.qt.io/terms-conditions. For further
 | 
					
						
							|  |  |  | ** information use the contact form at https://www.qt.io/contact-us.
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2016-01-15 14:57:40 +01:00
										 |  |  | ** GNU General Public License Usage | 
					
						
							|  |  |  | ** Alternatively, this file may be used under the terms of the GNU | 
					
						
							|  |  |  | ** General Public License version 3 as published by the Free Software | 
					
						
							|  |  |  | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT | 
					
						
							|  |  |  | ** included in the packaging of this file. Please review the following | 
					
						
							|  |  |  | ** information to ensure the GNU General Public License requirements will | 
					
						
							|  |  |  | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "androidconfigurations.h"
 | 
					
						
							|  |  |  | #include "androidconstants.h"
 | 
					
						
							| 
									
										
										
										
											2013-02-14 15:51:59 +01:00
										 |  |  | #include "androidtoolchain.h"
 | 
					
						
							|  |  |  | #include "androiddevice.h"
 | 
					
						
							| 
									
										
										
										
											2017-03-30 14:43:13 +02:00
										 |  |  | #include "androidmanager.h"
 | 
					
						
							| 
									
										
										
										
											2013-08-01 12:49:47 +02:00
										 |  |  | #include "androidqtversion.h"
 | 
					
						
							| 
									
										
										
										
											2013-09-10 19:19:31 +02:00
										 |  |  | #include "androiddevicedialog.h"
 | 
					
						
							| 
									
										
										
										
											2014-03-24 16:31:28 +01:00
										 |  |  | #include "avddialog.h"
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <coreplugin/icore.h>
 | 
					
						
							| 
									
										
										
										
											2013-11-22 16:40:41 +01:00
										 |  |  | #include <coreplugin/messagemanager.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-17 06:35:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-14 15:51:59 +01:00
										 |  |  | #include <projectexplorer/devicesupport/devicemanager.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-17 06:35:31 +02:00
										 |  |  | #include <projectexplorer/kitinformation.h>
 | 
					
						
							|  |  |  | #include <projectexplorer/kitmanager.h>
 | 
					
						
							| 
									
										
										
										
											2016-04-29 23:06:26 +02:00
										 |  |  | #include <projectexplorer/project.h>
 | 
					
						
							| 
									
										
										
										
											2020-07-23 15:48:56 +02:00
										 |  |  | #include <projectexplorer/projectexplorerconstants.h>
 | 
					
						
							| 
									
										
										
										
											2013-09-10 19:19:31 +02:00
										 |  |  | #include <projectexplorer/session.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-17 06:35:31 +02:00
										 |  |  | #include <projectexplorer/toolchainmanager.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-25 13:47:08 +02:00
										 |  |  | #include <debugger/debuggeritemmanager.h>
 | 
					
						
							| 
									
										
										
										
											2015-02-26 15:29:28 +01:00
										 |  |  | #include <debugger/debuggeritem.h>
 | 
					
						
							| 
									
										
										
										
											2013-02-14 15:51:59 +01:00
										 |  |  | #include <debugger/debuggerkitinformation.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-17 06:35:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-14 15:51:59 +01:00
										 |  |  | #include <qtsupport/baseqtversion.h>
 | 
					
						
							|  |  |  | #include <qtsupport/qtkitinformation.h>
 | 
					
						
							|  |  |  | #include <qtsupport/qtversionmanager.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-17 06:35:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-16 18:25:52 +04:00
										 |  |  | #include <utils/algorithm.h>
 | 
					
						
							| 
									
										
										
										
											2013-04-17 11:52:16 +02:00
										 |  |  | #include <utils/environment.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-17 06:35:31 +02:00
										 |  |  | #include <utils/environment.h>
 | 
					
						
							| 
									
										
										
										
											2016-04-29 23:06:26 +02:00
										 |  |  | #include <utils/hostosinfo.h>
 | 
					
						
							|  |  |  | #include <utils/persistentsettings.h>
 | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  | #include <utils/qtcassert.h>
 | 
					
						
							| 
									
										
										
										
											2016-02-05 15:06:15 +01:00
										 |  |  | #include <utils/runextensions.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-17 06:35:31 +02:00
										 |  |  | #include <utils/stringutils.h>
 | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  | #include <utils/synchronousprocess.h>
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-29 23:06:26 +02:00
										 |  |  | #include <QApplication>
 | 
					
						
							|  |  |  | #include <QDirIterator>
 | 
					
						
							|  |  |  | #include <QFileInfo>
 | 
					
						
							|  |  |  | #include <QHostAddress>
 | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  | #include <QJsonArray>
 | 
					
						
							|  |  |  | #include <QJsonDocument>
 | 
					
						
							|  |  |  | #include <QJsonObject>
 | 
					
						
							| 
									
										
										
										
											2017-05-05 12:26:23 +02:00
										 |  |  | #include <QLoggingCategory>
 | 
					
						
							| 
									
										
										
										
											2016-04-29 23:06:26 +02:00
										 |  |  | #include <QProcess>
 | 
					
						
							| 
									
										
										
										
											2017-05-05 12:26:23 +02:00
										 |  |  | #include <QRegularExpression>
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | #include <QSettings>
 | 
					
						
							| 
									
										
										
										
											2020-05-18 18:58:32 +03:00
										 |  |  | #include <QStandardPaths>
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | #include <QStringList>
 | 
					
						
							| 
									
										
										
										
											2015-04-23 16:25:44 +02:00
										 |  |  | #include <QTcpSocket>
 | 
					
						
							| 
									
										
										
										
											2016-09-20 11:22:05 +03:00
										 |  |  | #include <QThread>
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:16:45 +02:00
										 |  |  | #include <functional>
 | 
					
						
							| 
									
										
										
										
											2017-08-08 14:27:54 +02:00
										 |  |  | #include <memory>
 | 
					
						
							| 
									
										
										
										
											2014-06-19 14:16:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  | using namespace QtSupport; | 
					
						
							| 
									
										
										
										
											2012-08-09 01:56:51 +02:00
										 |  |  | using namespace ProjectExplorer; | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | using namespace Utils; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-05 12:26:23 +02:00
										 |  |  | namespace { | 
					
						
							| 
									
										
										
										
											2020-01-15 14:39:23 +01:00
										 |  |  | static Q_LOGGING_CATEGORY(avdConfigLog, "qtc.android.androidconfig", QtWarningMsg) | 
					
						
							| 
									
										
										
										
											2017-05-05 12:26:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | namespace Android { | 
					
						
							| 
									
										
										
										
											2014-06-25 15:42:11 +02:00
										 |  |  | using namespace Internal; | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  | const char JsonFilePath[] = "/android/sdk_definitions.json"; | 
					
						
							|  |  |  | const char SdkToolsUrlKey[] = "sdk_tools_url"; | 
					
						
							|  |  |  | const char CommonKey[] = "common"; | 
					
						
							|  |  |  | const char SdkEssentialPkgsKey[] = "sdk_essential_packages"; | 
					
						
							|  |  |  | const char VersionsKey[] = "versions"; | 
					
						
							|  |  |  | const char NdkPathKey[] = "ndk_path"; | 
					
						
							|  |  |  | const char SpecificQtVersionsKey[] = "specific_qt_versions"; | 
					
						
							|  |  |  | const char DefaultVersionKey[] = "default"; | 
					
						
							| 
									
										
										
										
											2020-03-13 13:50:46 +02:00
										 |  |  | const char LinuxOsKey[] = "linux"; | 
					
						
							|  |  |  | const char WindowsOsKey[] = "windows"; | 
					
						
							|  |  |  | const char macOsKey[] = "mac"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | namespace { | 
					
						
							| 
									
										
										
										
											2020-06-26 00:33:43 +03:00
										 |  |  |     const char jdk8SettingsPath[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit"; | 
					
						
							|  |  |  |     const char jdkLatestSettingsPath[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\JDK\\"; | 
					
						
							| 
									
										
										
										
											2017-04-12 14:08:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |     const QLatin1String SettingsGroup("AndroidConfigurations"); | 
					
						
							|  |  |  |     const QLatin1String SDKLocationKey("SDKLocation"); | 
					
						
							| 
									
										
										
										
											2020-02-24 11:19:02 +02:00
										 |  |  |     const QLatin1String CustomNdkLocationsKey("CustomNdkLocations"); | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  |     const QLatin1String SdkFullyConfiguredKey("AllEssentialsInstalled"); | 
					
						
							| 
									
										
										
										
											2017-09-27 15:26:59 +02:00
										 |  |  |     const QLatin1String SDKManagerToolArgsKey("SDKManagerToolArgs"); | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |     const QLatin1String OpenJDKLocationKey("OpenJDKLocation"); | 
					
						
							| 
									
										
										
										
											2020-02-28 19:27:03 +02:00
										 |  |  |     const QLatin1String OpenSslPriLocationKey("OpenSSLPriLocation"); | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |     const QLatin1String KeystoreLocationKey("KeystoreLocation"); | 
					
						
							| 
									
										
										
										
											2013-02-14 15:51:59 +01:00
										 |  |  |     const QLatin1String AutomaticKitCreationKey("AutomatiKitCreation"); | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |     const QLatin1String PartitionSizeKey("PartitionSize"); | 
					
						
							| 
									
										
										
										
											2014-11-18 18:37:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |     const QLatin1String ArmToolchainPrefix("arm-linux-androideabi"); | 
					
						
							|  |  |  |     const QLatin1String X86ToolchainPrefix("x86"); | 
					
						
							| 
									
										
										
										
											2014-11-18 18:37:05 +01:00
										 |  |  |     const QLatin1String AArch64ToolchainPrefix("aarch64-linux-android"); | 
					
						
							|  |  |  |     const QLatin1String X86_64ToolchainPrefix("x86_64"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |     const QLatin1String ArmToolsPrefix("arm-linux-androideabi"); | 
					
						
							| 
									
										
										
										
											2013-02-16 18:04:00 +02:00
										 |  |  |     const QLatin1String X86ToolsPrefix("i686-linux-android"); | 
					
						
							| 
									
										
										
										
											2014-11-18 18:37:05 +01:00
										 |  |  |     const QLatin1String AArch64ToolsPrefix("aarch64-linux-android"); | 
					
						
							|  |  |  |     const QLatin1String X86_64ToolsPrefix("x86_64-linux-android"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const QLatin1String ArmToolsDisplayName("arm"); | 
					
						
							|  |  |  |     const QLatin1String X86ToolsDisplayName("i686"); | 
					
						
							|  |  |  |     const QLatin1String AArch64ToolsDisplayName("aarch64"); | 
					
						
							|  |  |  |     const QLatin1String X86_64ToolsDisplayName("x86_64"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |     const QLatin1String Unknown("unknown"); | 
					
						
							|  |  |  |     const QLatin1String keytoolName("keytool"); | 
					
						
							|  |  |  |     const QLatin1String changeTimeStamp("ChangeTimeStamp"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 14:47:34 +02:00
										 |  |  |     const QLatin1String sdkToolsVersionKey("Pkg.Revision"); | 
					
						
							| 
									
										
										
										
											2017-05-05 12:26:23 +02:00
										 |  |  |     const QLatin1String ndkRevisionKey("Pkg.Revision"); | 
					
						
							| 
									
										
										
										
											2017-03-30 14:47:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-07 19:52:47 +02:00
										 |  |  |     static QString sdkSettingsFileName() | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-01-10 17:29:27 +01:00
										 |  |  |         return Core::ICore::installerResourcePath() + "/android.xml"; | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-31 16:09:34 +01:00
										 |  |  |     static bool is32BitUserSpace() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // Do the exact same check as android's emulator is doing:
 | 
					
						
							| 
									
										
										
										
											2015-02-03 23:50:37 +02:00
										 |  |  |         if (HostOsInfo::isLinuxHost()) { | 
					
						
							| 
									
										
										
										
											2014-10-31 16:09:34 +01:00
										 |  |  |             if (QSysInfo::WordSize == 32 ) { | 
					
						
							| 
									
										
										
										
											2015-02-03 23:50:37 +02:00
										 |  |  |                 Environment env = Environment::systemEnvironment(); | 
					
						
							| 
									
										
										
										
											2014-10-31 16:09:34 +01:00
										 |  |  |                 QString executable = env.searchInPath(QLatin1String("file")).toString(); | 
					
						
							|  |  |  |                 QString shell = env.value(QLatin1String("SHELL")); | 
					
						
							|  |  |  |                 if (executable.isEmpty() || shell.isEmpty()) | 
					
						
							|  |  |  |                     return true; // we can't detect, but creator is 32bit so assume 32bit
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  |                 SynchronousProcess proc; | 
					
						
							| 
									
										
										
										
											2014-10-31 16:09:34 +01:00
										 |  |  |                 proc.setProcessChannelMode(QProcess::MergedChannels); | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  |                 proc.setTimeoutS(30); | 
					
						
							| 
									
										
										
										
											2019-07-23 10:17:57 +02:00
										 |  |  |                 SynchronousProcessResponse response = proc.runBlocking({executable, {shell}}); | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  |                 if (response.result != SynchronousProcessResponse::Finished) | 
					
						
							| 
									
										
										
										
											2014-10-31 16:09:34 +01:00
										 |  |  |                     return true; | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  |                 return !response.allOutput().contains("x86-64"); | 
					
						
							| 
									
										
										
										
											2014-10-31 16:09:34 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | //////////////////////////////////
 | 
					
						
							|  |  |  | // AndroidConfig
 | 
					
						
							|  |  |  | //////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-18 18:37:05 +01:00
										 |  |  | QLatin1String AndroidConfig::toolchainPrefix(const Abi &abi) | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-11-18 18:37:05 +01:00
										 |  |  |     switch (abi.architecture()) { | 
					
						
							| 
									
										
										
										
											2012-08-09 01:56:51 +02:00
										 |  |  |     case Abi::ArmArchitecture: | 
					
						
							| 
									
										
										
										
											2014-11-18 18:37:05 +01:00
										 |  |  |         if (abi.wordWidth() == 64) | 
					
						
							|  |  |  |             return AArch64ToolchainPrefix; | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |         return ArmToolchainPrefix; | 
					
						
							| 
									
										
										
										
											2012-08-09 01:56:51 +02:00
										 |  |  |     case Abi::X86Architecture: | 
					
						
							| 
									
										
										
										
											2014-11-18 18:37:05 +01:00
										 |  |  |         if (abi.wordWidth() == 64) | 
					
						
							|  |  |  |             return X86_64ToolchainPrefix; | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |         return X86ToolchainPrefix; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         return Unknown; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-18 18:37:05 +01:00
										 |  |  | QLatin1String AndroidConfig::toolsPrefix(const Abi &abi) | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-11-18 18:37:05 +01:00
										 |  |  |     switch (abi.architecture()) { | 
					
						
							| 
									
										
										
										
											2012-08-09 01:56:51 +02:00
										 |  |  |     case Abi::ArmArchitecture: | 
					
						
							| 
									
										
										
										
											2014-11-18 18:37:05 +01:00
										 |  |  |         if (abi.wordWidth() == 64) | 
					
						
							|  |  |  |             return AArch64ToolsPrefix; | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |         return ArmToolsPrefix; | 
					
						
							| 
									
										
										
										
											2012-08-09 01:56:51 +02:00
										 |  |  |     case Abi::X86Architecture: | 
					
						
							| 
									
										
										
										
											2014-11-18 18:37:05 +01:00
										 |  |  |         if (abi.wordWidth() == 64) | 
					
						
							|  |  |  |             return X86_64ToolsPrefix; | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |         return X86ToolsPrefix; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         return Unknown; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-18 18:37:05 +01:00
										 |  |  | QLatin1String AndroidConfig::displayName(const Abi &abi) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     switch (abi.architecture()) { | 
					
						
							|  |  |  |     case Abi::ArmArchitecture: | 
					
						
							|  |  |  |         if (abi.wordWidth() == 64) | 
					
						
							|  |  |  |             return AArch64ToolsDisplayName; | 
					
						
							|  |  |  |         return ArmToolsDisplayName; | 
					
						
							|  |  |  |     case Abi::X86Architecture: | 
					
						
							|  |  |  |         if (abi.wordWidth() == 64) | 
					
						
							|  |  |  |             return X86_64ToolsDisplayName; | 
					
						
							|  |  |  |         return X86ToolsDisplayName; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         return Unknown; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | void AndroidConfig::load(const QSettings &settings) | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     // user settings
 | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  |     m_partitionSize = settings.value(PartitionSizeKey, 1024).toInt(); | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  |     m_sdkLocation = FilePath::fromString(settings.value(SDKLocationKey).toString()); | 
					
						
							| 
									
										
										
										
											2020-02-24 11:19:02 +02:00
										 |  |  |     m_customNdkList = settings.value(CustomNdkLocationsKey).toStringList(); | 
					
						
							| 
									
										
										
										
											2017-09-27 15:26:59 +02:00
										 |  |  |     m_sdkManagerToolArgs = settings.value(SDKManagerToolArgsKey).toStringList(); | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  |     m_openJDKLocation = FilePath::fromString(settings.value(OpenJDKLocationKey).toString()); | 
					
						
							| 
									
										
										
										
											2020-02-28 19:27:03 +02:00
										 |  |  |     m_openSslLocation = FilePath::fromString(settings.value(OpenSslPriLocationKey).toString()); | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  |     m_keystoreLocation = FilePath::fromString(settings.value(KeystoreLocationKey).toString()); | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  |     m_automaticKitCreation = settings.value(AutomaticKitCreationKey, true).toBool(); | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  |     m_sdkFullyConfigured = settings.value(SdkFullyConfiguredKey, false).toBool(); | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     PersistentSettingsReader reader; | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  |     if (reader.load(FilePath::fromString(sdkSettingsFileName())) | 
					
						
							| 
									
										
										
										
											2012-12-07 19:52:47 +02:00
										 |  |  |             && settings.value(changeTimeStamp).toInt() != QFileInfo(sdkSettingsFileName()).lastModified().toMSecsSinceEpoch() / 1000) { | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |         // persisten settings
 | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  |         m_sdkLocation = FilePath::fromString(reader.restoreValue(SDKLocationKey, m_sdkLocation.toString()).toString()); | 
					
						
							| 
									
										
										
										
											2020-02-24 11:19:02 +02:00
										 |  |  |         m_customNdkList = reader.restoreValue(CustomNdkLocationsKey).toStringList(); | 
					
						
							| 
									
										
										
										
											2017-09-27 15:26:59 +02:00
										 |  |  |         m_sdkManagerToolArgs = reader.restoreValue(SDKManagerToolArgsKey, m_sdkManagerToolArgs).toStringList(); | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  |         m_openJDKLocation = FilePath::fromString(reader.restoreValue(OpenJDKLocationKey, m_openJDKLocation.toString()).toString()); | 
					
						
							| 
									
										
										
										
											2020-02-28 19:27:03 +02:00
										 |  |  |         m_openSslLocation = FilePath::fromString(reader.restoreValue(OpenSslPriLocationKey, m_openSslLocation.toString()).toString()); | 
					
						
							| 
									
										
										
										
											2014-12-16 15:50:02 +01:00
										 |  |  |         m_automaticKitCreation = reader.restoreValue(AutomaticKitCreationKey, m_automaticKitCreation).toBool(); | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  |         m_sdkFullyConfigured = reader.restoreValue(SdkFullyConfiguredKey, m_sdkFullyConfigured).toBool(); | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |         // persistent settings
 | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-02-24 11:19:02 +02:00
										 |  |  |     m_customNdkList.removeAll(""); | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  |     parseDependenciesJson(); | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AndroidConfig::save(QSettings &settings) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-12-07 19:52:47 +02:00
										 |  |  |     QFileInfo fileInfo(sdkSettingsFileName()); | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |     if (fileInfo.exists()) | 
					
						
							|  |  |  |         settings.setValue(changeTimeStamp, fileInfo.lastModified().toMSecsSinceEpoch() / 1000); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // user settings
 | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  |     settings.setValue(SDKLocationKey, m_sdkLocation.toString()); | 
					
						
							| 
									
										
										
										
											2020-02-24 11:19:02 +02:00
										 |  |  |     settings.setValue(CustomNdkLocationsKey, m_customNdkList); | 
					
						
							| 
									
										
										
										
											2017-09-27 15:26:59 +02:00
										 |  |  |     settings.setValue(SDKManagerToolArgsKey, m_sdkManagerToolArgs); | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  |     settings.setValue(OpenJDKLocationKey, m_openJDKLocation.toString()); | 
					
						
							|  |  |  |     settings.setValue(KeystoreLocationKey, m_keystoreLocation.toString()); | 
					
						
							| 
									
										
										
										
											2020-02-28 19:27:03 +02:00
										 |  |  |     settings.setValue(OpenSslPriLocationKey, m_openSslLocation.toString()); | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  |     settings.setValue(PartitionSizeKey, m_partitionSize); | 
					
						
							|  |  |  |     settings.setValue(AutomaticKitCreationKey, m_automaticKitCreation); | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  |     settings.setValue(SdkFullyConfiguredKey, m_sdkFullyConfigured); | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  | void AndroidConfig::parseDependenciesJson() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-03-16 20:14:56 +02:00
										 |  |  |     QString sdkConfigUserFile(Core::ICore::userResourcePath() + JsonFilePath); | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  |     QString sdkConfigFile(Core::ICore::resourcePath() + JsonFilePath); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-16 20:14:56 +02:00
										 |  |  |     if (!QFile::exists(sdkConfigUserFile)) { | 
					
						
							|  |  |  |         QDir(QFileInfo(sdkConfigUserFile).absolutePath()).mkpath("."); | 
					
						
							|  |  |  |         QFile::copy(sdkConfigFile, sdkConfigUserFile); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (QFileInfo(sdkConfigFile).lastModified() > QFileInfo(sdkConfigUserFile).lastModified()) { | 
					
						
							|  |  |  |         QFile::remove(sdkConfigUserFile + ".old"); | 
					
						
							|  |  |  |         QFile::rename(sdkConfigUserFile, sdkConfigUserFile + ".old"); | 
					
						
							|  |  |  |         QFile::copy(sdkConfigFile, sdkConfigUserFile); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QFile jsonFile(sdkConfigUserFile); | 
					
						
							|  |  |  |     if (!jsonFile.open(QIODevice::ReadOnly)) { | 
					
						
							|  |  |  |         qCDebug(avdConfigLog, "Couldn't open JSON config file %s.", qPrintable(jsonFile.fileName())); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QJsonObject jsonObject = QJsonDocument::fromJson(jsonFile.readAll()).object(); | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (jsonObject.contains(CommonKey) && jsonObject[CommonKey].isObject()) { | 
					
						
							|  |  |  |         QJsonObject commonObject = jsonObject[CommonKey].toObject(); | 
					
						
							|  |  |  |         // Parse SDK Tools URL
 | 
					
						
							|  |  |  |         if (commonObject.contains(SdkToolsUrlKey) && commonObject[SdkToolsUrlKey].isObject()) { | 
					
						
							|  |  |  |             QJsonObject sdkToolsObj(commonObject[SdkToolsUrlKey].toObject()); | 
					
						
							|  |  |  |             if (Utils::HostOsInfo::isMacHost()) { | 
					
						
							| 
									
										
										
										
											2020-03-13 13:50:46 +02:00
										 |  |  |                 m_sdkToolsUrl = sdkToolsObj[macOsKey].toString(); | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  |                 m_sdkToolsSha256 = QByteArray::fromHex(sdkToolsObj["mac_sha256"].toString().toUtf8()); | 
					
						
							|  |  |  |             } else if (Utils::HostOsInfo::isWindowsHost()) { | 
					
						
							| 
									
										
										
										
											2020-03-13 13:50:46 +02:00
										 |  |  |                 m_sdkToolsUrl = sdkToolsObj[WindowsOsKey].toString(); | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  |                 m_sdkToolsSha256 = QByteArray::fromHex(sdkToolsObj["windows_sha256"].toString().toUtf8()); | 
					
						
							|  |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2020-03-13 13:50:46 +02:00
										 |  |  |                 m_sdkToolsUrl = sdkToolsObj[LinuxOsKey].toString(); | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  |                 m_sdkToolsSha256 = QByteArray::fromHex(sdkToolsObj["linux_sha256"].toString().toUtf8()); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Parse common essential packages
 | 
					
						
							| 
									
										
										
										
											2020-03-13 13:50:46 +02:00
										 |  |  |         auto appendEssentialsFromArray = [this](QJsonArray array) { | 
					
						
							|  |  |  |             for (const QJsonValueRef &pkg : array) | 
					
						
							|  |  |  |                 m_commonEssentialPkgs.append(pkg.toString()); | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QJsonObject commonEssentials = commonObject[SdkEssentialPkgsKey].toObject(); | 
					
						
							|  |  |  |         appendEssentialsFromArray(commonEssentials[DefaultVersionKey].toArray()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (Utils::HostOsInfo::isWindowsHost()) | 
					
						
							|  |  |  |             appendEssentialsFromArray(commonEssentials[WindowsOsKey].toArray()); | 
					
						
							|  |  |  |         if (Utils::HostOsInfo::isMacHost()) | 
					
						
							|  |  |  |             appendEssentialsFromArray(commonEssentials[macOsKey].toArray()); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             appendEssentialsFromArray(commonEssentials[LinuxOsKey].toArray()); | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto fillQtVersionsRange = [](const QString &shortVersion) { | 
					
						
							|  |  |  |         QList<QtVersionNumber> versions; | 
					
						
							|  |  |  |         QRegularExpression re("([0-9]\\.[0-9]*\\.)\\[([0-9])\\-([0-9])\\]"); | 
					
						
							|  |  |  |         QRegularExpressionMatch match = re.match(shortVersion); | 
					
						
							|  |  |  |         if (match.hasMatch() && match.lastCapturedIndex() == 3) | 
					
						
							|  |  |  |             for (int i = match.captured(2).toInt(); i <= match.captured(3).toInt(); ++i) | 
					
						
							|  |  |  |                 versions.append(QtVersionNumber(match.captured(1) + QString::number(i))); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             versions.append(QtVersionNumber(shortVersion)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return versions; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (jsonObject.contains(SpecificQtVersionsKey) && jsonObject[SpecificQtVersionsKey].isArray()) { | 
					
						
							|  |  |  |         QJsonArray versionsArray = jsonObject[SpecificQtVersionsKey].toArray(); | 
					
						
							|  |  |  |         for (const QJsonValueRef &item : versionsArray) { | 
					
						
							|  |  |  |             QJsonObject itemObj = item.toObject(); | 
					
						
							|  |  |  |             SdkForQtVersions specificVersion; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             specificVersion.ndkPath = itemObj[NdkPathKey].toString(); | 
					
						
							|  |  |  |             for (const QJsonValueRef &pkg : itemObj[SdkEssentialPkgsKey].toArray()) | 
					
						
							|  |  |  |                 specificVersion.essentialPackages.append(pkg.toString()); | 
					
						
							|  |  |  |             for (const QJsonValueRef &pkg : itemObj[VersionsKey].toArray()) | 
					
						
							|  |  |  |                 specificVersion.versions.append(fillQtVersionsRange(pkg.toString())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (itemObj[VersionsKey].toArray().first().toString() == DefaultVersionKey) | 
					
						
							|  |  |  |                 m_defaultSdkDepends = specificVersion; | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 m_specificQtVersions.append(specificVersion); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  | QVector<int> AndroidConfig::availableNdkPlatforms(const BaseQtVersion *qtVersion) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QVector<int> availableNdkPlatforms; | 
					
						
							|  |  |  |     QDirIterator it(ndkLocation(qtVersion).pathAppended("platforms").toString(), | 
					
						
							|  |  |  |                     QStringList("android-*"), | 
					
						
							|  |  |  |                     QDir::Dirs); | 
					
						
							|  |  |  |     while (it.hasNext()) { | 
					
						
							|  |  |  |         const QString &fileName = it.next(); | 
					
						
							|  |  |  |         availableNdkPlatforms.push_back( | 
					
						
							|  |  |  |             fileName.midRef(fileName.lastIndexOf(QLatin1Char('-')) + 1).toInt()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     Utils::sort(availableNdkPlatforms, std::greater<>()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return availableNdkPlatforms; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 11:19:02 +02:00
										 |  |  | QStringList AndroidConfig::getCustomNdkList() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_customNdkList; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AndroidConfig::addCustomNdk(const QString &customNdk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!m_customNdkList.contains(customNdk)) | 
					
						
							|  |  |  |         m_customNdkList.append(customNdk); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AndroidConfig::removeCustomNdk(const QString &customNdk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_customNdkList.removeAll(customNdk); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-28 19:27:03 +02:00
										 |  |  | Utils::FilePath AndroidConfig::openSslLocation() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_openSslLocation; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AndroidConfig::setOpenSslLocation(const Utils::FilePath &openSslLocation) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_openSslLocation = openSslLocation; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-18 08:22:34 +02:00
										 |  |  | QStringList AndroidConfig::apiLevelNamesFor(const SdkPlatformList &platforms) | 
					
						
							| 
									
										
										
										
											2014-03-24 16:31:28 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-07-16 12:35:29 +02:00
										 |  |  |     return Utils::transform(platforms, AndroidConfig::apiLevelNameFor); | 
					
						
							| 
									
										
										
										
											2014-03-24 16:31:28 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-18 08:22:34 +02:00
										 |  |  | QString AndroidConfig::apiLevelNameFor(const SdkPlatform *platform) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:23:08 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-08-18 08:22:34 +02:00
										 |  |  |     return platform && platform->apiLevel() > 0 ? | 
					
						
							|  |  |  |                 QString("android-%1").arg(platform->apiLevel()) : ""; | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-16 16:44:06 +03:00
										 |  |  | bool AndroidConfig::isCmdlineSdkToolsInstalled() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QString toolPath("cmdline-tools/latest/bin/sdkmanager"); | 
					
						
							|  |  |  |     if (HostOsInfo::isWindowsHost()) | 
					
						
							|  |  |  |         toolPath += ANDROID_BAT_SUFFIX; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return m_sdkLocation.pathAppended(toolPath).exists(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  | FilePath AndroidConfig::adbToolPath() const | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-19 17:35:56 +01:00
										 |  |  |     return m_sdkLocation / "platform-tools/adb" QTC_HOST_EXE_SUFFIX; | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  | FilePath AndroidConfig::emulatorToolPath() const | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-04-03 11:11:17 +02:00
										 |  |  |     QString relativePath = "emulator/emulator"; | 
					
						
							| 
									
										
										
										
											2020-04-16 16:44:06 +03:00
										 |  |  |     if (sdkToolsVersion() < QVersionNumber(25, 3, 0) && !isCmdlineSdkToolsInstalled()) | 
					
						
							| 
									
										
										
										
											2017-04-03 11:11:17 +02:00
										 |  |  |         relativePath = "tools/emulator"; | 
					
						
							| 
									
										
										
										
											2020-02-19 17:35:56 +01:00
										 |  |  |     return m_sdkLocation / (relativePath + QTC_HOST_EXE_SUFFIX); | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  | FilePath AndroidConfig::sdkManagerToolPath() const | 
					
						
							| 
									
										
										
										
											2017-03-30 14:47:34 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-04-16 16:44:06 +03:00
										 |  |  |     QStringList sdkmanagerPaths = {"cmdline-tools/latest/bin/sdkmanager", | 
					
						
							|  |  |  |                                    "tools/bin/sdkmanager"}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (QString &toolPath : sdkmanagerPaths) { | 
					
						
							|  |  |  |         if (HostOsInfo::isWindowsHost()) | 
					
						
							|  |  |  |             toolPath += ANDROID_BAT_SUFFIX; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-20 08:40:54 +02:00
										 |  |  |         const FilePath sdkmanagerPath = m_sdkLocation / toolPath; | 
					
						
							| 
									
										
										
										
											2020-04-16 16:44:06 +03:00
										 |  |  |         if (sdkmanagerPath.exists()) | 
					
						
							|  |  |  |             return sdkmanagerPath; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return FilePath(); | 
					
						
							| 
									
										
										
										
											2017-03-30 14:47:34 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  | FilePath AndroidConfig::avdManagerToolPath() const | 
					
						
							| 
									
										
										
										
											2017-04-03 11:11:17 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-04-16 16:44:06 +03:00
										 |  |  |     QStringList sdkmanagerPaths = {"cmdline-tools/latest/bin/avdmanager", | 
					
						
							|  |  |  |                                    "tools/bin/avdmanager"}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (QString &toolPath : sdkmanagerPaths) { | 
					
						
							|  |  |  |         if (HostOsInfo::isWindowsHost()) | 
					
						
							|  |  |  |             toolPath += ANDROID_BAT_SUFFIX; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-20 08:40:54 +02:00
										 |  |  |         const FilePath sdkmanagerPath = m_sdkLocation / toolPath; | 
					
						
							| 
									
										
										
										
											2020-04-16 16:44:06 +03:00
										 |  |  |         if (sdkmanagerPath.exists()) | 
					
						
							|  |  |  |             return sdkmanagerPath; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return FilePath(); | 
					
						
							| 
									
										
										
										
											2017-04-03 11:11:17 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  | FilePath AndroidConfig::aaptToolPath() const | 
					
						
							| 
									
										
										
										
											2018-07-03 11:53:25 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-19 17:35:56 +01:00
										 |  |  |     const FilePath aaptToolPath = m_sdkLocation / "build-tools"; | 
					
						
							| 
									
										
										
										
											2018-07-03 11:53:25 +02:00
										 |  |  |     QString toolPath = QString("%1/aapt").arg(buildToolsVersion().toString()); | 
					
						
							|  |  |  |     if (HostOsInfo::isWindowsHost()) | 
					
						
							| 
									
										
										
										
											2018-07-09 14:50:54 +02:00
										 |  |  |         toolPath += QTC_HOST_EXE_SUFFIX; | 
					
						
							| 
									
										
										
										
											2020-02-19 17:35:56 +01:00
										 |  |  |     return aaptToolPath / toolPath; | 
					
						
							| 
									
										
										
										
											2018-07-03 11:53:25 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 11:19:02 +02:00
										 |  |  | FilePath AndroidConfig::toolchainPathFromNdk(const Utils::FilePath &ndkLocation) const | 
					
						
							| 
									
										
										
										
											2013-04-04 01:29:47 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-19 17:35:56 +01:00
										 |  |  |     const FilePath toolchainPath = ndkLocation / "toolchains/llvm/prebuilt/"; | 
					
						
							| 
									
										
										
										
											2018-10-25 18:12:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // detect toolchain host
 | 
					
						
							|  |  |  |     QStringList hostPatterns; | 
					
						
							|  |  |  |     switch (HostOsInfo::hostOs()) { | 
					
						
							|  |  |  |     case OsTypeLinux: | 
					
						
							|  |  |  |         hostPatterns << QLatin1String("linux*"); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case OsTypeWindows: | 
					
						
							|  |  |  |         hostPatterns << QLatin1String("windows*"); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case OsTypeMac: | 
					
						
							|  |  |  |         hostPatterns << QLatin1String("darwin*"); | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  |     default: /* unknown host */ return FilePath(); | 
					
						
							| 
									
										
										
										
											2018-10-25 18:12:43 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-26 14:19:07 +03:00
										 |  |  |     QDirIterator iter(toolchainPath.toString(), hostPatterns, QDir::Dirs); | 
					
						
							|  |  |  |     if (iter.hasNext()) { | 
					
						
							|  |  |  |         iter.next(); | 
					
						
							| 
									
										
										
										
											2020-02-19 17:35:56 +01:00
										 |  |  |         return toolchainPath / iter.fileName(); | 
					
						
							| 
									
										
										
										
											2018-10-25 18:12:43 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-28 14:30:42 +01:00
										 |  |  |     return {}; | 
					
						
							| 
									
										
										
										
											2013-04-04 01:29:47 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 11:19:02 +02:00
										 |  |  | FilePath AndroidConfig::toolchainPath(const BaseQtVersion *qtVersion) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return toolchainPathFromNdk(ndkLocation(qtVersion)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | FilePath AndroidConfig::clangPathFromNdk(const Utils::FilePath &ndkLocation) const | 
					
						
							| 
									
										
										
										
											2019-08-26 14:19:07 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-24 11:19:02 +02:00
										 |  |  |     const FilePath path = toolchainPathFromNdk(ndkLocation); | 
					
						
							| 
									
										
										
										
											2019-08-26 14:19:07 +03:00
										 |  |  |     if (path.isEmpty()) | 
					
						
							|  |  |  |         return {}; | 
					
						
							| 
									
										
										
										
											2020-02-19 17:35:56 +01:00
										 |  |  |     return path / HostOsInfo::withExecutableSuffix("bin/clang"); | 
					
						
							| 
									
										
										
										
											2019-08-26 14:19:07 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  | FilePath AndroidConfig::gdbPath(const ProjectExplorer::Abi &abi, const BaseQtVersion *qtVersion) const | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-24 11:19:02 +02:00
										 |  |  |     return gdbPathFromNdk(abi, ndkLocation(qtVersion)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | FilePath AndroidConfig::gdbPathFromNdk(const Abi &abi, const FilePath &ndkLocation) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const FilePath path = ndkLocation.pathAppended( | 
					
						
							| 
									
										
										
										
											2020-07-16 08:17:01 +02:00
										 |  |  |         QString("prebuilt/%1/bin/gdb%2").arg(toolchainHostFromNdk(ndkLocation), | 
					
						
							|  |  |  |                                              QString(QTC_HOST_EXE_SUFFIX))); | 
					
						
							| 
									
										
										
										
											2018-11-28 14:30:42 +01:00
										 |  |  |     if (path.exists()) | 
					
						
							|  |  |  |         return path; | 
					
						
							|  |  |  |     // fallback for old NDKs (e.g. 10e)
 | 
					
						
							| 
									
										
										
										
											2020-02-24 11:19:02 +02:00
										 |  |  |     return ndkLocation.pathAppended(QString("toolchains/%1-4.9/prebuilt/%2/bin/%3-gdb%4") | 
					
						
							|  |  |  |                                                    .arg(toolchainPrefix(abi), | 
					
						
							|  |  |  |                                                         toolchainHostFromNdk(ndkLocation), | 
					
						
							|  |  |  |                                                         toolsPrefix(abi), | 
					
						
							| 
									
										
										
										
											2020-07-16 08:17:01 +02:00
										 |  |  |                                                         QString(QTC_HOST_EXE_SUFFIX))); | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  | FilePath AndroidConfig::makePathFromNdk(const FilePath &ndkLocation) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return ndkLocation.pathAppended( | 
					
						
							| 
									
										
										
										
											2020-07-16 08:17:01 +02:00
										 |  |  |                 QString("prebuilt/%1/bin/make%2").arg(toolchainHostFromNdk(ndkLocation), | 
					
						
							|  |  |  |                                                       QString(QTC_HOST_EXE_SUFFIX))); | 
					
						
							| 
									
										
										
										
											2017-11-06 15:59:11 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  | FilePath AndroidConfig::openJDKBinPath() const | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  |     const FilePath path = m_openJDKLocation; | 
					
						
							| 
									
										
										
										
											2012-04-24 15:49:09 +02:00
										 |  |  |     if (!path.isEmpty()) | 
					
						
							| 
									
										
										
										
											2019-05-15 08:15:19 +02:00
										 |  |  |         return path.pathAppended("bin"); | 
					
						
							| 
									
										
										
										
											2012-04-24 15:49:09 +02:00
										 |  |  |     return path; | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  | FilePath AndroidConfig::keytoolPath() const | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-15 08:15:19 +02:00
										 |  |  |     return openJDKBinPath().pathAppended(keytoolName); | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(QString *error) const | 
					
						
							| 
									
										
										
										
											2015-04-10 18:08:51 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-06 16:27:55 +02:00
										 |  |  |     return connectedDevices(adbToolPath(), error); | 
					
						
							| 
									
										
										
										
											2015-04-10 18:08:51 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-06 16:27:55 +02:00
										 |  |  | QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(const FilePath &adbToolPath, QString *error) | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-07-03 16:57:44 +03:00
										 |  |  |     QVector<AndroidDeviceInfo> devices; | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  |     SynchronousProcess adbProc; | 
					
						
							|  |  |  |     adbProc.setTimeoutS(30); | 
					
						
							| 
									
										
										
										
											2019-06-06 16:27:55 +02:00
										 |  |  |     CommandLine cmd{adbToolPath, {"devices"}}; | 
					
						
							|  |  |  |     SynchronousProcessResponse response = adbProc.runBlocking(cmd); | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  |     if (response.result != SynchronousProcessResponse::Finished) { | 
					
						
							| 
									
										
										
										
											2013-07-03 17:58:48 +02:00
										 |  |  |         if (error) | 
					
						
							| 
									
										
										
										
											2019-06-06 16:27:55 +02:00
										 |  |  |             *error = QApplication::translate("AndroidConfiguration", "Could not run: %1") | 
					
						
							|  |  |  |                 .arg(cmd.toUserOutput()); | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |         return devices; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-07-21 10:19:36 +02:00
										 |  |  |     QStringList adbDevs = response.allOutput().split('\n', Qt::SkipEmptyParts); | 
					
						
							| 
									
										
										
										
											2013-10-22 13:51:17 +03:00
										 |  |  |     if (adbDevs.empty()) | 
					
						
							|  |  |  |         return devices; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-03 13:45:30 +02:00
										 |  |  |     for (const QString &line : adbDevs) // remove the daemon logs
 | 
					
						
							| 
									
										
										
										
											2020-05-18 10:43:06 +03:00
										 |  |  |         if (line.startsWith("* daemon")) | 
					
						
							|  |  |  |             adbDevs.removeOne(line); | 
					
						
							| 
									
										
										
										
											2013-10-22 13:51:17 +03:00
										 |  |  |     adbDevs.removeFirst(); // remove "List of devices attached" header line
 | 
					
						
							| 
									
										
										
										
											2013-02-24 18:04:36 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // workaround for '????????????' serial numbers:
 | 
					
						
							|  |  |  |     // can use "adb -d" when only one usb device attached
 | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  |     foreach (const QString &device, adbDevs) { | 
					
						
							|  |  |  |         const QString serialNo = device.left(device.indexOf('\t')).trimmed(); | 
					
						
							|  |  |  |         const QString deviceType = device.mid(device.indexOf('\t')).trimmed(); | 
					
						
							| 
									
										
										
										
											2013-08-28 12:50:32 +02:00
										 |  |  |         AndroidDeviceInfo dev; | 
					
						
							| 
									
										
										
										
											2013-02-24 18:04:36 +04:00
										 |  |  |         dev.serialNumber = serialNo; | 
					
						
							| 
									
										
										
										
											2013-09-10 19:19:31 +02:00
										 |  |  |         dev.type = serialNo.startsWith(QLatin1String("emulator")) ? AndroidDeviceInfo::Emulator : AndroidDeviceInfo::Hardware; | 
					
						
							| 
									
										
										
										
											2015-04-10 18:08:51 +02:00
										 |  |  |         dev.sdk = getSDKVersion(adbToolPath, dev.serialNumber); | 
					
						
							|  |  |  |         dev.cpuAbi = getAbis(adbToolPath, dev.serialNumber); | 
					
						
							| 
									
										
										
										
											2014-03-10 15:18:46 +01:00
										 |  |  |         if (deviceType == QLatin1String("unauthorized")) | 
					
						
							|  |  |  |             dev.state = AndroidDeviceInfo::UnAuthorizedState; | 
					
						
							|  |  |  |         else if (deviceType == QLatin1String("offline")) | 
					
						
							|  |  |  |             dev.state = AndroidDeviceInfo::OfflineState; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             dev.state = AndroidDeviceInfo::OkState; | 
					
						
							| 
									
										
										
										
											2015-04-23 16:25:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-05 17:34:22 +03:00
										 |  |  |         if (dev.type == AndroidDeviceInfo::Emulator) { | 
					
						
							| 
									
										
										
										
											2015-04-23 16:25:44 +02:00
										 |  |  |             dev.avdname = getAvdName(dev.serialNumber); | 
					
						
							| 
									
										
										
										
											2016-05-05 17:34:22 +03:00
										 |  |  |             if (dev.avdname.isEmpty()) | 
					
						
							|  |  |  |                 dev.avdname = serialNo; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-04-23 16:25:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |         devices.push_back(dev); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-08-28 12:50:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 14:43:13 +02:00
										 |  |  |     Utils::sort(devices); | 
					
						
							| 
									
										
										
										
											2013-07-03 17:58:48 +02:00
										 |  |  |     if (devices.isEmpty() && error) | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  |         *error = QApplication::translate("AndroidConfiguration", | 
					
						
							|  |  |  |                                          "No devices found in output of: %1") | 
					
						
							| 
									
										
										
										
											2019-06-06 16:27:55 +02:00
										 |  |  |             .arg(cmd.toUserOutput()); | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |     return devices; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | bool AndroidConfig::isConnected(const QString &serialNumber) const | 
					
						
							| 
									
										
										
										
											2013-07-05 18:54:42 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-13 16:35:29 +01:00
										 |  |  |     QVector<AndroidDeviceInfo> devices = connectedDevices(); | 
					
						
							|  |  |  |     foreach (AndroidDeviceInfo device, devices) { | 
					
						
							|  |  |  |         if (device.serialNumber == serialNumber) | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-07-05 18:54:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-06 16:27:55 +02:00
										 |  |  | QString AndroidConfig::getDeviceProperty(const FilePath &adbToolPath, const QString &device, const QString &property) | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-02-24 18:04:36 +04:00
										 |  |  |     // workaround for '????????????' serial numbers
 | 
					
						
							| 
									
										
										
										
											2019-06-06 16:27:55 +02:00
										 |  |  |     CommandLine cmd(adbToolPath, AndroidDeviceInfo::adbSelector(device)); | 
					
						
							|  |  |  |     cmd.addArgs({"shell", "getprop", property}); | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  |     SynchronousProcess adbProc; | 
					
						
							|  |  |  |     adbProc.setTimeoutS(10); | 
					
						
							| 
									
										
										
										
											2019-06-06 16:27:55 +02:00
										 |  |  |     SynchronousProcessResponse response = adbProc.runBlocking(cmd); | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  |     if (response.result != SynchronousProcessResponse::Finished) | 
					
						
							| 
									
										
										
										
											2015-04-10 16:46:30 +02:00
										 |  |  |         return QString(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  |     return response.allOutput(); | 
					
						
							| 
									
										
										
										
											2015-04-10 16:46:30 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int AndroidConfig::getSDKVersion(const QString &device) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-06 16:27:55 +02:00
										 |  |  |     return getSDKVersion(adbToolPath(), device); | 
					
						
							| 
									
										
										
										
											2015-04-10 18:08:51 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-06 16:27:55 +02:00
										 |  |  | int AndroidConfig::getSDKVersion(const FilePath &adbToolPath, const QString &device) | 
					
						
							| 
									
										
										
										
											2015-04-10 18:08:51 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-06 16:27:55 +02:00
										 |  |  |     QString tmp = getDeviceProperty(adbToolPath, device, "ro.build.version.sdk"); | 
					
						
							| 
									
										
										
										
											2015-04-10 16:46:30 +02:00
										 |  |  |     if (tmp.isEmpty()) | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2015-04-10 16:46:30 +02:00
										 |  |  |     return tmp.trimmed().toInt(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-23 16:25:44 +02:00
										 |  |  | QString AndroidConfig::getAvdName(const QString &serialnumber) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int index = serialnumber.indexOf(QLatin1String("-")); | 
					
						
							|  |  |  |     if (index == -1) | 
					
						
							|  |  |  |         return QString(); | 
					
						
							|  |  |  |     bool ok; | 
					
						
							| 
									
										
										
										
											2016-02-03 13:49:53 +01:00
										 |  |  |     int port = serialnumber.midRef(index + 1).toInt(&ok); | 
					
						
							| 
									
										
										
										
											2015-04-23 16:25:44 +02:00
										 |  |  |     if (!ok) | 
					
						
							|  |  |  |         return QString(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-29 08:54:00 +02:00
										 |  |  |     const QByteArray avdName = "avd name\n"; | 
					
						
							| 
									
										
										
										
											2015-04-23 16:25:44 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     QTcpSocket tcpSocket; | 
					
						
							|  |  |  |     tcpSocket.connectToHost(QHostAddress(QHostAddress::LocalHost), port); | 
					
						
							| 
									
										
										
										
											2016-05-05 17:34:22 +03:00
										 |  |  |     if (!tcpSocket.waitForConnected(100)) // Don't wait more than 100ms for a local connection
 | 
					
						
							|  |  |  |         return QString{}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-23 16:25:44 +02:00
										 |  |  |     tcpSocket.write(avdName + "exit\n"); | 
					
						
							| 
									
										
										
										
											2016-05-05 17:34:22 +03:00
										 |  |  |     tcpSocket.waitForDisconnected(500); | 
					
						
							| 
									
										
										
										
											2015-04-23 16:25:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-29 08:54:00 +02:00
										 |  |  |     QByteArray name; | 
					
						
							|  |  |  |     const QByteArrayList response = tcpSocket.readAll().split('\n'); | 
					
						
							|  |  |  |     // The input "avd name" might not be echoed as-is, but contain ASCII
 | 
					
						
							|  |  |  |     // control sequences.
 | 
					
						
							|  |  |  |     for (int i = response.size() - 1; i > 1; --i) { | 
					
						
							| 
									
										
										
										
											2016-08-25 15:46:50 +03:00
										 |  |  |         if (response.at(i).startsWith("OK")) { | 
					
						
							| 
									
										
										
										
											2016-04-29 08:54:00 +02:00
										 |  |  |             name = response.at(i - 1); | 
					
						
							| 
									
										
										
										
											2016-08-25 15:46:50 +03:00
										 |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-04-29 08:54:00 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     return QString::fromLatin1(name).trimmed(); | 
					
						
							| 
									
										
										
										
											2015-04-23 16:25:44 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-10 16:46:30 +02:00
										 |  |  | AndroidConfig::OpenGl AndroidConfig::getOpenGLEnabled(const QString &emulator) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QDir dir = QDir::home(); | 
					
						
							|  |  |  |     if (!dir.cd(QLatin1String(".android"))) | 
					
						
							|  |  |  |         return OpenGl::Unknown; | 
					
						
							|  |  |  |     if (!dir.cd(QLatin1String("avd"))) | 
					
						
							|  |  |  |         return OpenGl::Unknown; | 
					
						
							|  |  |  |     if (!dir.cd(emulator + QLatin1String(".avd"))) | 
					
						
							|  |  |  |         return OpenGl::Unknown; | 
					
						
							|  |  |  |     QFile file(dir.filePath(QLatin1String("config.ini"))); | 
					
						
							|  |  |  |     if (!file.exists()) | 
					
						
							|  |  |  |         return OpenGl::Unknown; | 
					
						
							|  |  |  |     if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) | 
					
						
							|  |  |  |         return OpenGl::Unknown; | 
					
						
							|  |  |  |     while (!file.atEnd()) { | 
					
						
							|  |  |  |         QByteArray line = file.readLine(); | 
					
						
							|  |  |  |         if (line.contains("hw.gpu.enabled") && line.contains("yes")) | 
					
						
							|  |  |  |             return OpenGl::Enabled; | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-04-10 16:46:30 +02:00
										 |  |  |     return OpenGl::Disabled; | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-03 17:58:48 +02:00
										 |  |  | //!
 | 
					
						
							|  |  |  | //! \brief AndroidConfigurations::getProductModel
 | 
					
						
							|  |  |  | //! \param device serial number
 | 
					
						
							|  |  |  | //! \return the produce model of the device or if that cannot be read the serial number
 | 
					
						
							|  |  |  | //!
 | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | QString AndroidConfig::getProductModel(const QString &device) const | 
					
						
							| 
									
										
										
										
											2013-07-03 17:58:48 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-09-10 19:19:31 +02:00
										 |  |  |     if (m_serialNumberToDeviceName.contains(device)) | 
					
						
							|  |  |  |         return m_serialNumberToDeviceName.value(device); | 
					
						
							| 
									
										
										
										
											2013-07-03 17:58:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-06 16:27:55 +02:00
										 |  |  |     QString model = getDeviceProperty(adbToolPath(), device, "ro.product.model").trimmed(); | 
					
						
							| 
									
										
										
										
											2013-07-03 17:58:48 +02:00
										 |  |  |     if (model.isEmpty()) | 
					
						
							|  |  |  |         return device; | 
					
						
							| 
									
										
										
										
											2015-04-10 16:46:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-10 19:19:31 +02:00
										 |  |  |     if (!device.startsWith(QLatin1String("????"))) | 
					
						
							|  |  |  |         m_serialNumberToDeviceName.insert(device, model); | 
					
						
							| 
									
										
										
										
											2013-07-03 17:58:48 +02:00
										 |  |  |     return model; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | QStringList AndroidConfig::getAbis(const QString &device) const | 
					
						
							| 
									
										
										
										
											2015-04-10 18:08:51 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-06 16:27:55 +02:00
										 |  |  |     return getAbis(adbToolPath(), device); | 
					
						
							| 
									
										
										
										
											2015-04-10 18:08:51 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-06 16:27:55 +02:00
										 |  |  | QStringList AndroidConfig::getAbis(const FilePath &adbToolPath, const QString &device) | 
					
						
							| 
									
										
										
										
											2013-05-03 15:10:21 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     QStringList result; | 
					
						
							| 
									
										
										
										
											2014-11-18 12:55:21 +01:00
										 |  |  |     // First try via ro.product.cpu.abilist
 | 
					
						
							|  |  |  |     QStringList arguments = AndroidDeviceInfo::adbSelector(device); | 
					
						
							| 
									
										
										
										
											2019-06-06 16:27:55 +02:00
										 |  |  |     arguments << "shell" << "getprop" << "ro.product.cpu.abilist"; | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  |     SynchronousProcess adbProc; | 
					
						
							|  |  |  |     adbProc.setTimeoutS(10); | 
					
						
							| 
									
										
										
										
											2019-06-06 16:27:55 +02:00
										 |  |  |     SynchronousProcessResponse response = adbProc.runBlocking({adbToolPath, arguments}); | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  |     if (response.result != SynchronousProcessResponse::Finished) | 
					
						
							| 
									
										
										
										
											2014-11-18 12:55:21 +01:00
										 |  |  |         return result; | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     QString output = response.allOutput().trimmed(); | 
					
						
							| 
									
										
										
										
											2014-11-18 12:55:21 +01:00
										 |  |  |     if (!output.isEmpty()) { | 
					
						
							|  |  |  |         QStringList result = output.split(QLatin1Char(',')); | 
					
						
							|  |  |  |         if (!result.isEmpty()) | 
					
						
							|  |  |  |             return result; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Fall back to ro.product.cpu.abi, ro.product.cpu.abi2 ...
 | 
					
						
							| 
									
										
										
										
											2013-11-15 16:45:55 +01:00
										 |  |  |     for (int i = 1; i < 6; ++i) { | 
					
						
							| 
									
										
										
										
											2013-05-03 15:10:21 +02:00
										 |  |  |         QStringList arguments = AndroidDeviceInfo::adbSelector(device); | 
					
						
							|  |  |  |         arguments << QLatin1String("shell") << QLatin1String("getprop"); | 
					
						
							|  |  |  |         if (i == 1) | 
					
						
							|  |  |  |             arguments << QLatin1String("ro.product.cpu.abi"); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             arguments << QString::fromLatin1("ro.product.cpu.abi%1").arg(i); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  |         SynchronousProcess abiProc; | 
					
						
							|  |  |  |         abiProc.setTimeoutS(10); | 
					
						
							| 
									
										
										
										
											2019-06-06 16:27:55 +02:00
										 |  |  |         SynchronousProcessResponse abiResponse = abiProc.runBlocking({adbToolPath, arguments}); | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  |         if (abiResponse.result != SynchronousProcessResponse::Finished) | 
					
						
							| 
									
										
										
										
											2013-05-03 15:10:21 +02:00
										 |  |  |             return result; | 
					
						
							| 
									
										
										
										
											2016-04-29 16:52:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         QString abi = abiResponse.allOutput().trimmed(); | 
					
						
							| 
									
										
										
										
											2013-05-03 15:10:21 +02:00
										 |  |  |         if (abi.isEmpty()) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         result << abi; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 11:19:02 +02:00
										 |  |  | bool AndroidConfig::isValidNdk(const QString &ndkLocation) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto ndkPath = Utils::FilePath::fromUserInput(ndkLocation); | 
					
						
							|  |  |  |     const Utils::FilePath ndkPlatformsDir = ndkPath.pathAppended("platforms"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ndkPath.exists() && ndkPath.pathAppended("toolchains").exists() | 
					
						
							|  |  |  |            && ndkPlatformsDir.exists() && !ndkPlatformsDir.toString().contains(' ') | 
					
						
							|  |  |  |            && !ndkVersion(ndkPath).isNull(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  | QString AndroidConfig::bestNdkPlatformMatch(int target, const BaseQtVersion *qtVersion) const | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-06-18 13:17:49 +02:00
										 |  |  |     target = std::max(AndroidManager::apiLevelRange().first, target); | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  |     foreach (int apiLevel, availableNdkPlatforms(qtVersion)) { | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |         if (apiLevel <= target) | 
					
						
							|  |  |  |             return QString::fromLatin1("android-%1").arg(apiLevel); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-06-18 13:17:49 +02:00
										 |  |  |     return QString("android-%1").arg(AndroidManager::apiLevelRange().first); | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  | FilePath AndroidConfig::sdkLocation() const | 
					
						
							| 
									
										
										
										
											2013-05-16 15:49:24 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  |     return m_sdkLocation; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  | void AndroidConfig::setSdkLocation(const FilePath &sdkLocation) | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     m_sdkLocation = sdkLocation; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 14:47:34 +02:00
										 |  |  | QVersionNumber AndroidConfig::sdkToolsVersion() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QVersionNumber version; | 
					
						
							|  |  |  |     if (m_sdkLocation.exists()) { | 
					
						
							| 
									
										
										
										
											2020-04-16 16:44:06 +03:00
										 |  |  |         FilePath sdkToolsPropertiesPath; | 
					
						
							|  |  |  |         if (isCmdlineSdkToolsInstalled()) | 
					
						
							| 
									
										
										
										
											2020-04-20 08:40:54 +02:00
										 |  |  |             sdkToolsPropertiesPath = m_sdkLocation / "cmdline-tools/latest/source.properties"; | 
					
						
							| 
									
										
										
										
											2020-04-16 16:44:06 +03:00
										 |  |  |         else | 
					
						
							| 
									
										
										
										
											2020-04-20 08:40:54 +02:00
										 |  |  |             sdkToolsPropertiesPath = m_sdkLocation / "tools/source.properties"; | 
					
						
							| 
									
										
										
										
											2017-03-30 14:47:34 +02:00
										 |  |  |         QSettings settings(sdkToolsPropertiesPath.toString(), QSettings::IniFormat); | 
					
						
							|  |  |  |         auto versionStr = settings.value(sdkToolsVersionKey).toString(); | 
					
						
							|  |  |  |         version = QVersionNumber::fromString(versionStr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return version; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-04 14:54:50 +02:00
										 |  |  | QVersionNumber AndroidConfig::buildToolsVersion() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  |     //TODO: return version according to qt version
 | 
					
						
							| 
									
										
										
										
											2017-09-04 14:54:50 +02:00
										 |  |  |     QVersionNumber maxVersion; | 
					
						
							| 
									
										
										
										
											2019-05-17 13:20:41 +02:00
										 |  |  |     QDir buildToolsDir(m_sdkLocation.pathAppended("build-tools").toString()); | 
					
						
							| 
									
										
										
										
											2020-05-12 13:01:44 +02:00
										 |  |  |     for (const QFileInfo &file: buildToolsDir.entryInfoList(QDir::Dirs|QDir::NoDotAndDotDot)) | 
					
						
							| 
									
										
										
										
											2017-09-04 14:54:50 +02:00
										 |  |  |         maxVersion = qMax(maxVersion, QVersionNumber::fromString(file.fileName())); | 
					
						
							|  |  |  |     return maxVersion; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-27 15:26:59 +02:00
										 |  |  | QStringList AndroidConfig::sdkManagerToolArgs() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_sdkManagerToolArgs; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AndroidConfig::setSdkManagerToolArgs(const QStringList &args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_sdkManagerToolArgs = args; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  | FilePath AndroidConfig::ndkLocation(const BaseQtVersion *qtVersion) const | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  |     return sdkLocation().pathAppended(ndkPathFromQtVersion(*qtVersion)); | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  | FilePath AndroidConfig::defaultNdkLocation() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return sdkLocation().pathAppended(m_defaultSdkDepends.ndkPath); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  | QVersionNumber AndroidConfig::ndkVersion(const BaseQtVersion *qtVersion) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return ndkVersion(ndkLocation(qtVersion)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QVersionNumber AndroidConfig::ndkVersion(const FilePath &ndkPath) const | 
					
						
							| 
									
										
										
										
											2017-05-05 12:26:23 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     QVersionNumber version; | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  |     if (!ndkPath.exists()) { | 
					
						
							| 
									
										
										
										
											2018-10-22 16:34:31 +02:00
										 |  |  |         qCDebug(avdConfigLog) << "Cannot find ndk version. Check NDK path." | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  |                               << ndkPath.toString(); | 
					
						
							| 
									
										
										
										
											2017-05-05 12:26:23 +02:00
										 |  |  |         return version; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  |     const FilePath ndkPropertiesPath = ndkPath.pathAppended("source.properties"); | 
					
						
							| 
									
										
										
										
											2017-05-05 12:26:23 +02:00
										 |  |  |     if (ndkPropertiesPath.exists()) { | 
					
						
							|  |  |  |         // source.properties files exists in NDK version > 11
 | 
					
						
							|  |  |  |         QSettings settings(ndkPropertiesPath.toString(), QSettings::IniFormat); | 
					
						
							|  |  |  |         auto versionStr = settings.value(ndkRevisionKey).toString(); | 
					
						
							|  |  |  |         version = QVersionNumber::fromString(versionStr); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         // No source.properties. There should be a file named RELEASE.TXT
 | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  |         const FilePath ndkReleaseTxtPath = ndkPath.pathAppended("RELEASE.TXT"); | 
					
						
							| 
									
										
										
										
											2017-05-05 12:26:23 +02:00
										 |  |  |         Utils::FileReader reader; | 
					
						
							|  |  |  |         QString errorString; | 
					
						
							|  |  |  |         if (reader.fetch(ndkReleaseTxtPath.toString(), &errorString)) { | 
					
						
							|  |  |  |             // RELEASE.TXT contains the ndk version in either of the following formats:
 | 
					
						
							|  |  |  |             // r6a
 | 
					
						
							|  |  |  |             // r10e (64 bit)
 | 
					
						
							|  |  |  |             QString content = QString::fromUtf8(reader.data()); | 
					
						
							|  |  |  |             QRegularExpression re("(r)(?<major>[0-9]{1,2})(?<minor>[a-z]{1,1})"); | 
					
						
							|  |  |  |             QRegularExpressionMatch match = re.match(content); | 
					
						
							|  |  |  |             if (match.hasMatch()) { | 
					
						
							|  |  |  |                 QString major = match.captured("major"); | 
					
						
							|  |  |  |                 QString minor = match.captured("minor"); | 
					
						
							|  |  |  |                 // Minor version: a = 0, b = 1, c = 2 and so on.
 | 
					
						
							|  |  |  |                 // Int equivalent = minorVersionChar - 'a'. i.e. minorVersionChar - 97.
 | 
					
						
							|  |  |  |                 version = QVersionNumber::fromString(QString("%1.%2.0").arg(major) | 
					
						
							|  |  |  |                                                      .arg((int)minor[0].toLatin1() - 97)); | 
					
						
							|  |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2018-10-22 16:34:31 +02:00
										 |  |  |                 qCDebug(avdConfigLog) << "Cannot find ndk version. Cannot parse RELEASE.TXT." | 
					
						
							| 
									
										
										
										
											2017-05-05 12:26:23 +02:00
										 |  |  |                                       << content; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2018-10-22 16:34:31 +02:00
										 |  |  |             qCDebug(avdConfigLog) << "Cannot find ndk version." << errorString; | 
					
						
							| 
									
										
										
										
											2017-05-05 12:26:23 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return version; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  | QStringList AndroidConfig::allEssentials() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QList<BaseQtVersion *> installedVersions = QtVersionManager::versions( | 
					
						
							|  |  |  |         [](const BaseQtVersion *v) { | 
					
						
							|  |  |  |             return v->targetDeviceTypes().contains(Android::Constants::ANDROID_DEVICE_TYPE); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QStringList allPackages(defaultEssentials()); | 
					
						
							|  |  |  |     for (const BaseQtVersion *version : installedVersions) | 
					
						
							|  |  |  |         allPackages.append(essentialsFromQtVersion(*version)); | 
					
						
							|  |  |  |     allPackages.removeDuplicates(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return allPackages; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-01 23:42:34 +03:00
										 |  |  | bool AndroidConfig::allEssentialsInstalled(AndroidSdkManager *sdkManager) | 
					
						
							| 
									
										
										
										
											2020-05-18 18:58:32 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     QStringList essentialPkgs(allEssentials()); | 
					
						
							| 
									
										
										
										
											2020-07-01 23:42:34 +03:00
										 |  |  |     for (const AndroidSdkPackage *pkg : sdkManager->installedSdkPackages()) { | 
					
						
							| 
									
										
										
										
											2020-05-18 18:58:32 +03:00
										 |  |  |         if (essentialPkgs.contains(pkg->sdkStylePath())) | 
					
						
							|  |  |  |             essentialPkgs.removeOne(pkg->sdkStylePath()); | 
					
						
							|  |  |  |         if (essentialPkgs.isEmpty()) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return essentialPkgs.isEmpty() ? true : false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool AndroidConfig::sdkToolsOk() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     bool exists = sdkLocation().exists(); | 
					
						
							|  |  |  |     bool writable = sdkLocation().isWritablePath(); | 
					
						
							|  |  |  |     bool sdkToolsExist = !sdkToolsVersion().isNull(); | 
					
						
							|  |  |  |     return exists && writable && sdkToolsExist; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  | QStringList AndroidConfig::essentialsFromQtVersion(const BaseQtVersion &version) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QtVersionNumber qtVersion = version.qtVersion(); | 
					
						
							|  |  |  |     for (const SdkForQtVersions &item : m_specificQtVersions) | 
					
						
							|  |  |  |         if (item.containsVersion(qtVersion)) | 
					
						
							|  |  |  |             return item.essentialPackages; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return m_defaultSdkDepends.essentialPackages; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QString AndroidConfig::ndkPathFromQtVersion(const BaseQtVersion &version) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  |     QtVersionNumber qtVersion(version.qtVersionString()); | 
					
						
							| 
									
										
										
										
											2019-12-23 16:13:23 +02:00
										 |  |  |     for (const SdkForQtVersions &item : m_specificQtVersions) | 
					
						
							|  |  |  |         if (item.containsVersion(qtVersion)) | 
					
						
							|  |  |  |             return item.ndkPath; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return m_defaultSdkDepends.ndkPath; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QStringList AndroidConfig::defaultEssentials() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_defaultSdkDepends.essentialPackages + m_commonEssentialPkgs; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool SdkForQtVersions::containsVersion(const QtVersionNumber &qtVersion) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return versions.contains(qtVersion) | 
					
						
							|  |  |  |            || versions.contains(QtVersionNumber(qtVersion.majorVersion, qtVersion.minorVersion)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  | FilePath AndroidConfig::openJDKLocation() const | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     return m_openJDKLocation; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  | void AndroidConfig::setOpenJDKLocation(const FilePath &openJDKLocation) | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     m_openJDKLocation = openJDKLocation; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  | FilePath AndroidConfig::keystoreLocation() const | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     return m_keystoreLocation; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  | void AndroidConfig::setKeystoreLocation(const FilePath &keystoreLocation) | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     m_keystoreLocation = keystoreLocation; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  | QString AndroidConfig::toolchainHost(const BaseQtVersion *qtVersion) const | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  |     return toolchainHostFromNdk(ndkLocation(qtVersion)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QString AndroidConfig::toolchainHostFromNdk(const FilePath &ndkPath) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // detect toolchain host
 | 
					
						
							|  |  |  |     QString toolchainHost; | 
					
						
							|  |  |  |     QStringList hostPatterns; | 
					
						
							|  |  |  |     switch (HostOsInfo::hostOs()) { | 
					
						
							|  |  |  |     case OsTypeLinux: | 
					
						
							|  |  |  |         hostPatterns << QLatin1String("linux*"); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case OsTypeWindows: | 
					
						
							|  |  |  |         hostPatterns << QLatin1String("windows*"); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case OsTypeMac: | 
					
						
							|  |  |  |         hostPatterns << QLatin1String("darwin*"); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     default: /* unknown host */ | 
					
						
							|  |  |  |         return toolchainHost; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QDirIterator jt(ndkPath.pathAppended("prebuilt").toString(), | 
					
						
							|  |  |  |                     hostPatterns, | 
					
						
							|  |  |  |                     QDir::Dirs); | 
					
						
							|  |  |  |     if (jt.hasNext()) { | 
					
						
							|  |  |  |         jt.next(); | 
					
						
							|  |  |  |         toolchainHost = jt.fileName(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return toolchainHost; | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | unsigned AndroidConfig::partitionSize() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_partitionSize; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AndroidConfig::setPartitionSize(unsigned partitionSize) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_partitionSize = partitionSize; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool AndroidConfig::automaticKitCreation() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_automaticKitCreation; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AndroidConfig::setAutomaticKitCreation(bool b) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_automaticKitCreation = b; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-18 18:58:32 +03:00
										 |  |  | FilePath AndroidConfig::defaultSdkPath() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QString sdkFromEnvVar = QString::fromLocal8Bit(getenv("ANDROID_SDK_ROOT")); | 
					
						
							|  |  |  |     if (!sdkFromEnvVar.isEmpty()) | 
					
						
							|  |  |  |         return Utils::FilePath::fromString(sdkFromEnvVar); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Set default path of SDK as used by Android Studio
 | 
					
						
							|  |  |  |     if (Utils::HostOsInfo::isMacHost()) { | 
					
						
							|  |  |  |         return Utils::FilePath::fromString( | 
					
						
							|  |  |  |             QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) | 
					
						
							|  |  |  |             + "/../Android/sdk"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (Utils::HostOsInfo::isWindowsHost()) { | 
					
						
							|  |  |  |         return Utils::FilePath::fromString( | 
					
						
							| 
									
										
										
										
											2020-07-01 09:01:26 +02:00
										 |  |  |             QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/Android/Sdk"); | 
					
						
							| 
									
										
										
										
											2020-05-18 18:58:32 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return Utils::FilePath::fromString( | 
					
						
							|  |  |  |         QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/Android/Sdk"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | ///////////////////////////////////
 | 
					
						
							|  |  |  | // AndroidConfigurations
 | 
					
						
							|  |  |  | ///////////////////////////////////
 | 
					
						
							|  |  |  | void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-18 16:57:44 +01:00
										 |  |  |     emit m_instance->aboutToUpdate(); | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  |     m_instance->m_config = devConfigs; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_instance->save(); | 
					
						
							|  |  |  |     m_instance->updateAndroidDevice(); | 
					
						
							| 
									
										
										
										
											2015-04-22 17:42:23 +02:00
										 |  |  |     m_instance->registerNewToolChains(); | 
					
						
							| 
									
										
										
										
											2014-03-11 13:05:36 +01:00
										 |  |  |     m_instance->updateAutomaticKitList(); | 
					
						
							| 
									
										
										
										
											2015-04-22 17:42:23 +02:00
										 |  |  |     m_instance->removeOldToolChains(); | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  |     emit m_instance->updated(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-03 23:50:37 +02:00
										 |  |  | AndroidDeviceInfo AndroidConfigurations::showDeviceDialog(Project *project, | 
					
						
							| 
									
										
										
										
											2019-08-26 14:19:07 +03:00
										 |  |  |                                                           int apiLevel, const QStringList &abis) | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-08-26 14:19:07 +03:00
										 |  |  |     QString serialNumber; | 
					
						
							|  |  |  |     for (const QString &abi : abis) { | 
					
						
							|  |  |  |         serialNumber = defaultDevice(project, abi); | 
					
						
							|  |  |  |         if (!serialNumber.isEmpty()) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-06-02 09:10:40 +02:00
										 |  |  |     AndroidDeviceDialog dialog(apiLevel, abis, serialNumber, Core::ICore::dialogParent()); | 
					
						
							| 
									
										
										
										
											2015-12-04 10:03:45 +02:00
										 |  |  |     AndroidDeviceInfo info = dialog.device(); | 
					
						
							|  |  |  |     if (dialog.saveDeviceSelection() && info.isValid()) { | 
					
						
							|  |  |  |         const QString serialNumber = info.type == AndroidDeviceInfo::Hardware ? | 
					
						
							|  |  |  |                     info.serialNumber : info.avdname; | 
					
						
							|  |  |  |         if (!serialNumber.isEmpty()) | 
					
						
							| 
									
										
										
										
											2019-08-26 14:19:07 +03:00
										 |  |  |             AndroidConfigurations::setDefaultDevice(project, AndroidManager::devicePreferredAbi(info.cpuAbi, abis), serialNumber); | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-12-04 10:03:45 +02:00
										 |  |  |     return info; | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-03 23:50:37 +02:00
										 |  |  | void AndroidConfigurations::clearDefaultDevices(Project *project) | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     if (m_instance->m_defaultDeviceForAbi.contains(project)) | 
					
						
							|  |  |  |         m_instance->m_defaultDeviceForAbi.remove(project); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-03 23:50:37 +02:00
										 |  |  | void AndroidConfigurations::setDefaultDevice(Project *project, const QString &abi, const QString &serialNumber) | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     m_instance->m_defaultDeviceForAbi[project][abi] = serialNumber; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QString AndroidConfigurations::defaultDevice(Project *project, const QString &abi) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!m_instance->m_defaultDeviceForAbi.contains(project)) | 
					
						
							|  |  |  |         return QString(); | 
					
						
							|  |  |  |     const QMap<QString, QString> &map = m_instance->m_defaultDeviceForAbi.value(project); | 
					
						
							|  |  |  |     if (!map.contains(abi)) | 
					
						
							|  |  |  |         return QString(); | 
					
						
							|  |  |  |     return map.value(abi); | 
					
						
							| 
									
										
										
										
											2013-05-16 15:49:24 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-24 15:53:37 +02:00
										 |  |  | static bool matchToolChain(const ToolChain *atc, const ToolChain *btc) | 
					
						
							| 
									
										
										
										
											2013-02-14 15:51:59 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-04-22 17:42:23 +02:00
										 |  |  |     if (atc == btc) | 
					
						
							|  |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2016-10-24 15:53:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!atc || !btc) | 
					
						
							| 
									
										
										
										
											2015-04-22 17:42:23 +02:00
										 |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2016-10-24 15:53:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-14 11:12:19 +02:00
										 |  |  |     if (atc->typeId() != Constants::ANDROID_TOOLCHAIN_TYPEID || btc->typeId() != Constants::ANDROID_TOOLCHAIN_TYPEID) | 
					
						
							| 
									
										
										
										
											2015-04-22 17:42:23 +02:00
										 |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2016-10-24 15:53:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto aatc = static_cast<const AndroidToolChain *>(atc); | 
					
						
							|  |  |  |     auto abtc = static_cast<const AndroidToolChain *>(btc); | 
					
						
							| 
									
										
										
										
											2018-10-25 18:12:43 +02:00
										 |  |  |     return aatc->targetAbi() == abtc->targetAbi(); | 
					
						
							| 
									
										
										
										
											2016-10-24 15:53:37 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-22 17:42:23 +02:00
										 |  |  | void AndroidConfigurations::registerNewToolChains() | 
					
						
							| 
									
										
										
										
											2014-03-11 13:05:36 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-10-15 16:01:40 +02:00
										 |  |  |     const QList<ToolChain *> existingAndroidToolChains | 
					
						
							| 
									
										
										
										
											2017-01-11 16:12:32 +01:00
										 |  |  |             = ToolChainManager::toolChains(Utils::equal(&ToolChain::typeId, | 
					
						
							| 
									
										
										
										
											2020-06-26 13:59:38 +02:00
										 |  |  |                                                         Utils::Id(Constants::ANDROID_TOOLCHAIN_TYPEID))); | 
					
						
							| 
									
										
										
										
											2020-02-24 11:19:02 +02:00
										 |  |  |     QList<ToolChain *> newToolchains = AndroidToolChainFactory::autodetectToolChains( | 
					
						
							|  |  |  |         existingAndroidToolChains); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-15 16:01:40 +02:00
										 |  |  |     foreach (ToolChain *tc, newToolchains) | 
					
						
							| 
									
										
										
										
											2017-01-11 16:14:31 +01:00
										 |  |  |         ToolChainManager::registerToolChain(tc); | 
					
						
							| 
									
										
										
										
											2020-02-24 11:19:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     registerCustomToolChainsAndDebuggers(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AndroidConfigurations::registerCustomToolChainsAndDebuggers() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const QList<ToolChain *> existingAndroidToolChains = ToolChainManager::toolChains( | 
					
						
							| 
									
										
										
										
											2020-06-26 13:59:38 +02:00
										 |  |  |         Utils::equal(&ToolChain::typeId, Utils::Id(Constants::ANDROID_TOOLCHAIN_TYPEID))); | 
					
						
							| 
									
										
										
										
											2020-02-24 11:19:02 +02:00
										 |  |  |     QList<FilePath> customNdks = Utils::transform(currentConfig().getCustomNdkList(), | 
					
						
							|  |  |  |                                                   FilePath::fromString); | 
					
						
							|  |  |  |     QList<ToolChain *> customToolchains | 
					
						
							|  |  |  |         = AndroidToolChainFactory::autodetectToolChainsFromNdks(existingAndroidToolChains, | 
					
						
							|  |  |  |                                                                 customNdks, | 
					
						
							|  |  |  |                                                                 true); | 
					
						
							|  |  |  |     for (ToolChain *tc : customToolchains) { | 
					
						
							|  |  |  |         ToolChainManager::registerToolChain(tc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const FilePath ndk = static_cast<AndroidToolChain *>(tc)->ndkLocation(); | 
					
						
							|  |  |  |         const FilePath command = AndroidConfigurations::currentConfig() | 
					
						
							|  |  |  |                                      .gdbPathFromNdk(tc->targetAbi(), ndk); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const Debugger::DebuggerItem *existing = Debugger::DebuggerItemManager::findByCommand( | 
					
						
							|  |  |  |             command); | 
					
						
							|  |  |  |         QString abiStr | 
					
						
							|  |  |  |             = static_cast<AndroidToolChain *>(tc)->platformLinkerFlags().at(1).split('-').first(); | 
					
						
							|  |  |  |         Abi abi = Abi::abiFromTargetTriplet(abiStr); | 
					
						
							|  |  |  |         if (existing && existing->abis().contains(abi)) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Debugger::DebuggerItem debugger; | 
					
						
							|  |  |  |         debugger.setCommand(command); | 
					
						
							|  |  |  |         debugger.setEngineType(Debugger::GdbEngineType); | 
					
						
							|  |  |  |         debugger.setUnexpandedDisplayName( | 
					
						
							|  |  |  |             AndroidConfigurations::tr("Custom Android Debugger (%1, NDK %2)") | 
					
						
							|  |  |  |                 .arg(abiStr, | 
					
						
							|  |  |  |                      AndroidConfigurations::currentConfig().ndkVersion(ndk).toString())); | 
					
						
							|  |  |  |         debugger.setAutoDetected(true); | 
					
						
							|  |  |  |         debugger.setAbi(abi); | 
					
						
							|  |  |  |         debugger.reinitializeFromFile(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Debugger::DebuggerItemManager::registerDebugger(debugger); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-04-22 17:42:23 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-03-11 13:05:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-22 17:42:23 +02:00
										 |  |  | void AndroidConfigurations::removeOldToolChains() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-06-26 13:59:38 +02:00
										 |  |  |     foreach (ToolChain *tc, ToolChainManager::toolChains(Utils::equal(&ToolChain::typeId, Utils::Id(Constants::ANDROID_TOOLCHAIN_TYPEID)))) { | 
					
						
							| 
									
										
										
										
											2017-01-11 16:12:32 +01:00
										 |  |  |         if (!tc->isValid()) | 
					
						
							|  |  |  |             ToolChainManager::deregisterToolChain(tc); | 
					
						
							| 
									
										
										
										
											2014-03-11 13:05:36 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 00:19:28 +02:00
										 |  |  | void AndroidConfigurations::removeUnusedDebuggers() | 
					
						
							| 
									
										
										
										
											2018-11-28 14:30:42 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-25 00:19:28 +02:00
										 |  |  |     QList<FilePath> uniqueNdks; | 
					
						
							|  |  |  |     const QList<QtSupport::BaseQtVersion *> qtVersions | 
					
						
							|  |  |  |         = QtSupport::QtVersionManager::versions([](const QtSupport::BaseQtVersion *v) { | 
					
						
							|  |  |  |               return v->type() == Constants::ANDROIDQT; | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (const QtSupport::BaseQtVersion *qt : qtVersions) { | 
					
						
							|  |  |  |         FilePath ndkLocation = currentConfig().ndkLocation(qt); | 
					
						
							|  |  |  |         if (!uniqueNdks.contains(ndkLocation)) | 
					
						
							|  |  |  |             uniqueNdks.append(ndkLocation); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 11:19:02 +02:00
										 |  |  |     uniqueNdks.append(Utils::transform(currentConfig().getCustomNdkList(), FilePath::fromString)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 00:19:28 +02:00
										 |  |  |     const QList<Debugger::DebuggerItem> allDebuggers = Debugger::DebuggerItemManager::debuggers(); | 
					
						
							|  |  |  |     for (const Debugger::DebuggerItem &debugger : allDebuggers) { | 
					
						
							|  |  |  |         if (!debugger.displayName().contains("Android")) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         bool isChildOfNdk = false; | 
					
						
							|  |  |  |         for (const FilePath &path : uniqueNdks) { | 
					
						
							|  |  |  |             if (debugger.command().isChildOf(path)) { | 
					
						
							|  |  |  |                 isChildOfNdk = true; | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!isChildOfNdk && debugger.isAutoDetected()) | 
					
						
							|  |  |  |             Debugger::DebuggerItemManager::deregisterDebugger(debugger.id()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-02 09:32:27 +03:00
										 |  |  | static bool containsAllAbis(const QStringList &abis) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-23 15:48:56 +02:00
										 |  |  |     QStringList supportedAbis{ | 
					
						
							|  |  |  |         ProjectExplorer::Constants::ANDROID_ABI_ARMEABI_V7A, | 
					
						
							|  |  |  |         ProjectExplorer::Constants::ANDROID_ABI_ARM64_V8A, | 
					
						
							|  |  |  |         ProjectExplorer::Constants::ANDROID_ABI_X86, | 
					
						
							|  |  |  |         ProjectExplorer::Constants::ANDROID_ABI_X86_64, | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2020-06-02 09:32:27 +03:00
										 |  |  |     for (const QString &abi : abis) | 
					
						
							|  |  |  |         if (supportedAbis.contains(abi)) | 
					
						
							|  |  |  |             supportedAbis.removeOne(abi); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return supportedAbis.isEmpty(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 00:19:28 +02:00
										 |  |  | static QVariant findOrRegisterDebugger(ToolChain *tc, | 
					
						
							|  |  |  |                                        const QStringList &abisList, | 
					
						
							|  |  |  |                                        const BaseQtVersion *qtVersion) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const FilePath command = AndroidConfigurations::currentConfig().gdbPath(tc->targetAbi(), | 
					
						
							|  |  |  |                                                                             qtVersion); | 
					
						
							| 
									
										
										
										
											2018-11-28 14:30:42 +01:00
										 |  |  |     // check if the debugger is already registered, but ignoring the display name
 | 
					
						
							|  |  |  |     const Debugger::DebuggerItem *existing = Debugger::DebuggerItemManager::findByCommand(command); | 
					
						
							| 
									
										
										
										
											2020-02-25 00:19:28 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     QList<Abi> abis = Utils::transform(abisList, Abi::abiFromTargetTriplet); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto containsAbis = [abis](const Abis &secondAbis) { | 
					
						
							|  |  |  |         for (const Abi &abi : secondAbis) { | 
					
						
							|  |  |  |             if (!abis.contains(abi)) | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-28 14:30:42 +01:00
										 |  |  |     if (existing && existing->engineType() == Debugger::GdbEngineType && existing->isAutoDetected() | 
					
						
							| 
									
										
										
										
											2020-02-25 00:19:28 +02:00
										 |  |  |         && containsAbis(existing->abis())) { | 
					
						
							|  |  |  |         // update debugger info with new
 | 
					
						
							| 
									
										
										
										
											2018-11-28 14:30:42 +01:00
										 |  |  |         return existing->id(); | 
					
						
							| 
									
										
										
										
											2020-02-25 00:19:28 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-28 14:30:42 +01:00
										 |  |  |     // debugger not found, register a new one
 | 
					
						
							|  |  |  |     Debugger::DebuggerItem debugger; | 
					
						
							| 
									
										
										
										
											2019-06-11 19:06:27 +02:00
										 |  |  |     debugger.setCommand(command); | 
					
						
							| 
									
										
										
										
											2018-11-28 14:30:42 +01:00
										 |  |  |     debugger.setEngineType(Debugger::GdbEngineType); | 
					
						
							|  |  |  |     debugger.setUnexpandedDisplayName( | 
					
						
							| 
									
										
										
										
											2020-02-25 00:19:28 +02:00
										 |  |  |         AndroidConfigurations::tr("Android Debugger (%1, NDK %2)") | 
					
						
							| 
									
										
										
										
											2020-06-02 09:32:27 +03:00
										 |  |  |             .arg(containsAllAbis(abisList) ? "Multi-Abi" : abisList.join(",")) | 
					
						
							|  |  |  |             .arg(AndroidConfigurations::currentConfig().ndkVersion(qtVersion).toString())); | 
					
						
							| 
									
										
										
										
											2018-11-28 14:30:42 +01:00
										 |  |  |     debugger.setAutoDetected(true); | 
					
						
							| 
									
										
										
										
											2020-02-25 00:19:28 +02:00
										 |  |  |     debugger.setAbis(abis.toVector()); | 
					
						
							| 
									
										
										
										
											2018-11-28 14:30:42 +01:00
										 |  |  |     debugger.reinitializeFromFile(); | 
					
						
							|  |  |  |     return Debugger::DebuggerItemManager::registerDebugger(debugger); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-14 15:51:59 +01:00
										 |  |  | void AndroidConfigurations::updateAutomaticKitList() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-04-30 16:41:39 +02:00
										 |  |  |     for (Kit *k : KitManager::kits()) { | 
					
						
							|  |  |  |         if (DeviceTypeKitAspect::deviceTypeId(k) == Constants::ANDROID_DEVICE_TYPE) { | 
					
						
							|  |  |  |             if (k->value(Constants::ANDROID_KIT_NDK).isNull() || k->value(Constants::ANDROID_KIT_SDK).isNull()) { | 
					
						
							|  |  |  |                 if (BaseQtVersion *qt = QtKitAspect::qtVersion(k)) { | 
					
						
							|  |  |  |                     k->setValueSilently(Constants::ANDROID_KIT_NDK, currentConfig().ndkLocation(qt).toString()); | 
					
						
							|  |  |  |                     k->setValue(Constants::ANDROID_KIT_SDK, currentConfig().sdkLocation().toString()); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-04-03 18:10:35 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 09:57:51 +02:00
										 |  |  |     const QList<Kit *> existingKits = Utils::filtered(KitManager::kits(), [](Kit *k) { | 
					
						
							| 
									
										
										
										
											2020-06-26 13:59:38 +02:00
										 |  |  |         Utils::Id deviceTypeId = DeviceTypeKitAspect::deviceTypeId(k); | 
					
						
							| 
									
										
										
										
											2017-05-19 09:57:51 +02:00
										 |  |  |         if (k->isAutoDetected() && !k->isSdkProvided() | 
					
						
							| 
									
										
										
										
											2020-06-26 13:59:38 +02:00
										 |  |  |                 && deviceTypeId == Utils::Id(Constants::ANDROID_DEVICE_TYPE)) { | 
					
						
							| 
									
										
										
										
											2019-02-06 12:50:51 +01:00
										 |  |  |             if (!QtSupport::QtKitAspect::qtVersion(k)) | 
					
						
							| 
									
										
										
										
											2017-05-19 09:57:51 +02:00
										 |  |  |                 KitManager::deregisterKit(k); // Remove autoDetected kits without Qt.
 | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2016-10-26 14:40:21 +02:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2013-02-14 15:51:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 00:19:28 +02:00
										 |  |  |     removeUnusedDebuggers(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-26 14:40:21 +02:00
										 |  |  |     QHash<Abi, QList<const QtSupport::BaseQtVersion *> > qtVersionsForArch; | 
					
						
							|  |  |  |     const QList<QtSupport::BaseQtVersion *> qtVersions | 
					
						
							| 
									
										
										
										
											2017-01-12 10:37:29 +01:00
										 |  |  |             = QtSupport::QtVersionManager::versions([](const QtSupport::BaseQtVersion *v) { | 
					
						
							| 
									
										
										
										
											2016-10-26 14:40:21 +02:00
										 |  |  |         return v->type() == Constants::ANDROIDQT; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     for (const QtSupport::BaseQtVersion *qtVersion : qtVersions) { | 
					
						
							| 
									
										
										
										
											2019-05-27 11:04:18 +02:00
										 |  |  |         const Abis qtAbis = qtVersion->qtAbis(); | 
					
						
							| 
									
										
										
										
											2013-02-25 09:17:43 +02:00
										 |  |  |         if (qtAbis.empty()) | 
					
						
							|  |  |  |             continue; | 
					
						
							| 
									
										
										
										
											2014-11-18 18:37:05 +01:00
										 |  |  |         qtVersionsForArch[qtAbis.first()].append(qtVersion); | 
					
						
							| 
									
										
										
										
											2013-02-14 15:51:59 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-23 09:21:18 +02:00
										 |  |  |     DeviceManager *dm = DeviceManager::instance(); | 
					
						
							| 
									
										
										
										
											2020-06-26 13:59:38 +02:00
										 |  |  |     IDevice::ConstPtr device = dm->find(Utils::Id(Constants::ANDROID_DEVICE_ID)); | 
					
						
							| 
									
										
										
										
											2013-10-30 17:02:28 +01:00
										 |  |  |     if (device.isNull()) { | 
					
						
							|  |  |  |         // no device, means no sdk path
 | 
					
						
							| 
									
										
										
										
											2016-10-26 14:40:21 +02:00
										 |  |  |         for (Kit *k : existingKits) | 
					
						
							| 
									
										
										
										
											2013-10-30 17:02:28 +01:00
										 |  |  |             KitManager::deregisterKit(k); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-02-14 15:51:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // register new kits
 | 
					
						
							| 
									
										
										
										
											2018-10-25 18:12:43 +02:00
										 |  |  |     const QList<ToolChain *> toolchains = ToolChainManager::toolChains([](const ToolChain *tc) { | 
					
						
							| 
									
										
										
										
											2016-10-24 15:53:37 +02:00
										 |  |  |         return tc->isAutoDetected() | 
					
						
							|  |  |  |             && tc->isValid() | 
					
						
							| 
									
										
										
										
											2019-06-14 11:12:19 +02:00
										 |  |  |             && tc->typeId() == Constants::ANDROID_TOOLCHAIN_TYPEID; | 
					
						
							| 
									
										
										
										
											2016-10-24 15:53:37 +02:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2018-10-25 18:12:43 +02:00
										 |  |  |     for (ToolChain *tc : toolchains) { | 
					
						
							| 
									
										
										
										
											2020-06-26 13:59:38 +02:00
										 |  |  |         if (tc->language() != Utils::Id(ProjectExplorer::Constants::CXX_LANGUAGE_ID)) | 
					
						
							| 
									
										
										
										
											2013-10-10 18:04:27 +02:00
										 |  |  |             continue; | 
					
						
							| 
									
										
										
										
											2019-03-12 11:49:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-18 10:37:19 +02:00
										 |  |  |         for (const QtSupport::BaseQtVersion *qt : qtVersionsForArch.value(tc->targetAbi())) { | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  |             FilePath tcNdk = static_cast<const AndroidToolChain *>(tc)->ndkLocation(); | 
					
						
							|  |  |  |             if (tcNdk != currentConfig().ndkLocation(qt)) | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             const QList<ToolChain *> allLanguages | 
					
						
							|  |  |  |                 = Utils::filtered(toolchains, [tc, tcNdk](ToolChain *otherTc) { | 
					
						
							|  |  |  |                       FilePath otherNdk = static_cast<const AndroidToolChain *>(otherTc)->ndkLocation(); | 
					
						
							|  |  |  |                       return tc->targetAbi() == otherTc->targetAbi() && tcNdk == otherNdk; | 
					
						
							|  |  |  |                   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-26 13:59:38 +02:00
										 |  |  |             QHash<Utils::Id, ToolChain *> toolChainForLanguage; | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  |             for (ToolChain *tc : allLanguages) | 
					
						
							|  |  |  |                 toolChainForLanguage[tc->language()] = tc; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-12 11:49:39 +01:00
										 |  |  |             Kit *existingKit = Utils::findOrDefault(existingKits, [&](const Kit *b) { | 
					
						
							|  |  |  |                 if (qt != QtSupport::QtKitAspect::qtVersion(b)) | 
					
						
							| 
									
										
										
										
											2019-03-11 16:59:16 +01:00
										 |  |  |                     return false; | 
					
						
							| 
									
										
										
										
											2019-03-12 11:49:39 +01:00
										 |  |  |                 return matchToolChain(toolChainForLanguage[ProjectExplorer::Constants::CXX_LANGUAGE_ID], | 
					
						
							| 
									
										
										
										
											2020-02-18 18:25:26 +01:00
										 |  |  |                                       ToolChainKitAspect::cxxToolChain(b)) | 
					
						
							| 
									
										
										
										
											2019-03-12 11:49:39 +01:00
										 |  |  |                         && matchToolChain(toolChainForLanguage[ProjectExplorer::Constants::C_LANGUAGE_ID], | 
					
						
							| 
									
										
										
										
											2020-02-18 18:25:26 +01:00
										 |  |  |                                           ToolChainKitAspect::cToolChain(b)); | 
					
						
							| 
									
										
										
										
											2019-03-12 11:49:39 +01:00
										 |  |  |             }); | 
					
						
							| 
									
										
										
										
											2019-03-12 14:07:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             const auto initializeKit = [allLanguages, device, tc, qt](Kit *k) { | 
					
						
							|  |  |  |                 k->setAutoDetected(true); | 
					
						
							|  |  |  |                 k->setAutoDetectionSource("AndroidConfiguration"); | 
					
						
							| 
									
										
										
										
											2020-06-26 13:59:38 +02:00
										 |  |  |                 DeviceTypeKitAspect::setDeviceTypeId(k, Utils::Id(Constants::ANDROID_DEVICE_TYPE)); | 
					
						
							| 
									
										
										
										
											2019-03-12 14:07:43 +01:00
										 |  |  |                 for (ToolChain *tc : allLanguages) | 
					
						
							|  |  |  |                     ToolChainKitAspect::setToolChain(k, tc); | 
					
						
							|  |  |  |                 QtSupport::QtKitAspect::setQtVersion(k, qt); | 
					
						
							|  |  |  |                 DeviceKitAspect::setDevice(k, device); | 
					
						
							| 
									
										
										
										
											2020-02-25 00:19:28 +02:00
										 |  |  |                 QStringList abis = static_cast<const AndroidQtVersion *>(qt)->androidAbis(); | 
					
						
							|  |  |  |                 Debugger::DebuggerKitAspect::setDebugger(k, findOrRegisterDebugger(tc, abis, QtKitAspect::qtVersion(k))); | 
					
						
							| 
									
										
										
										
											2019-03-12 14:07:43 +01:00
										 |  |  |                 k->makeSticky(); | 
					
						
							| 
									
										
										
										
											2020-07-02 14:47:43 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 QString versionStr = QLatin1String("Qt %{Qt:Version}"); | 
					
						
							|  |  |  |                 if (!qt->isAutodetected()) | 
					
						
							| 
									
										
										
										
											2020-07-08 11:01:16 +02:00
										 |  |  |                     versionStr = QString("%1").arg(qt->displayName()); | 
					
						
							| 
									
										
										
										
											2020-07-02 14:47:43 +03:00
										 |  |  |                 k->setUnexpandedDisplayName(tr("Android %1 Clang %2") | 
					
						
							|  |  |  |                                                 .arg(versionStr) | 
					
						
							| 
									
										
										
										
											2020-06-02 09:32:27 +03:00
										 |  |  |                                                 .arg(containsAllAbis(abis) ? "Multi-Abi" : abis.join(","))); | 
					
						
							| 
									
										
										
										
											2020-02-16 20:46:23 +02:00
										 |  |  |                 k->setValueSilently(Constants::ANDROID_KIT_NDK, currentConfig().ndkLocation(qt).toString()); | 
					
						
							| 
									
										
										
										
											2019-04-03 18:10:35 +02:00
										 |  |  |                 k->setValueSilently(Constants::ANDROID_KIT_SDK, currentConfig().sdkLocation().toString()); | 
					
						
							| 
									
										
										
										
											2019-03-12 14:07:43 +01:00
										 |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (existingKit) | 
					
						
							|  |  |  |                 initializeKit(existingKit); // Update the existing kit with new data.
 | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 KitManager::registerKit(initializeKit); | 
					
						
							| 
									
										
										
										
											2013-08-28 13:34:24 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-02-14 15:51:59 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-31 16:09:34 +01:00
										 |  |  | bool AndroidConfigurations::force32bitEmulator() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_instance->m_force32bit; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-10 09:58:19 +02:00
										 |  |  | QProcessEnvironment AndroidConfigurations::toolsEnvironment(const AndroidConfig &config) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Environment env = Environment::systemEnvironment(); | 
					
						
							| 
									
										
										
										
											2019-05-28 13:49:26 +02:00
										 |  |  |     Utils::FilePath jdkLocation = config.openJDKLocation(); | 
					
						
							| 
									
										
										
										
											2017-10-10 09:58:19 +02:00
										 |  |  |     if (!jdkLocation.isEmpty()) { | 
					
						
							|  |  |  |         env.set("JAVA_HOME", jdkLocation.toUserOutput()); | 
					
						
							| 
									
										
										
										
											2019-05-17 13:28:38 +02:00
										 |  |  |         env.prependOrSetPath(jdkLocation.pathAppended("bin").toUserOutput()); | 
					
						
							| 
									
										
										
										
											2017-10-10 09:58:19 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     return env.toProcessEnvironment(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-24 18:04:36 +04:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Workaround for '????????????' serial numbers | 
					
						
							|  |  |  |  * @return ("-d") for buggy devices, ("-s", <serial no>) for normal | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | QStringList AndroidDeviceInfo::adbSelector(const QString &serialNumber) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (serialNumber.startsWith(QLatin1String("????"))) | 
					
						
							| 
									
										
										
										
											2017-02-07 16:59:21 +01:00
										 |  |  |         return QStringList("-d"); | 
					
						
							| 
									
										
										
										
											2017-02-22 15:09:35 +01:00
										 |  |  |     return QStringList({"-s",  serialNumber}); | 
					
						
							| 
									
										
										
										
											2013-02-24 18:04:36 +04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 14:43:13 +02:00
										 |  |  | bool AndroidDeviceInfo::operator<(const AndroidDeviceInfo &other) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (serialNumber.contains("????") != other.serialNumber.contains("????")) | 
					
						
							|  |  |  |         return !serialNumber.contains("????"); | 
					
						
							|  |  |  |     if (type != other.type) | 
					
						
							|  |  |  |         return type == AndroidDeviceInfo::Hardware; | 
					
						
							|  |  |  |     if (sdk != other.sdk) | 
					
						
							|  |  |  |         return sdk < other.sdk; | 
					
						
							|  |  |  |     if (avdname != other.avdname) | 
					
						
							|  |  |  |         return avdname < other.avdname; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return serialNumber < other.serialNumber; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-07 13:44:20 +01:00
										 |  |  | const AndroidConfig &AndroidConfigurations::currentConfig() | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  |     return m_instance->m_config; // ensure that m_instance is initialized
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-18 08:22:34 +02:00
										 |  |  | AndroidSdkManager *AndroidConfigurations::sdkManager() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_instance->m_sdkManager.get(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | AndroidConfigurations *AndroidConfigurations::instance() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_instance; | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AndroidConfigurations::save() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-09-20 23:17:22 +02:00
										 |  |  |     QSettings *settings = Core::ICore::settings(); | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  |     settings->beginGroup(SettingsGroup); | 
					
						
							|  |  |  |     m_config.save(*settings); | 
					
						
							|  |  |  |     settings->endGroup(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-26 14:57:01 +01:00
										 |  |  | AndroidConfigurations::AndroidConfigurations() | 
					
						
							|  |  |  |     : m_sdkManager(new AndroidSdkManager(m_config)) | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     load(); | 
					
						
							| 
									
										
										
										
											2013-09-10 19:19:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-29 23:06:26 +02:00
										 |  |  |     connect(SessionManager::instance(), &SessionManager::projectRemoved, | 
					
						
							|  |  |  |             this, &AndroidConfigurations::clearDefaultDevices); | 
					
						
							| 
									
										
										
										
											2018-02-09 16:16:38 +01:00
										 |  |  |     connect(DeviceManager::instance(), &DeviceManager::devicesLoaded, | 
					
						
							|  |  |  |             this, &AndroidConfigurations::updateAndroidDevice); | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-31 16:09:34 +01:00
										 |  |  |     m_force32bit = is32BitUserSpace(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-16 20:19:07 +01:00
										 |  |  |     m_instance = this; | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-25 12:19:15 +02:00
										 |  |  | AndroidConfigurations::~AndroidConfigurations() = default; | 
					
						
							| 
									
										
										
										
											2017-08-18 08:22:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:07:48 +02:00
										 |  |  | static Utils::FilePath androidStudioPath() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (Utils::HostOsInfo::isWindowsHost()) { | 
					
						
							|  |  |  |         const QLatin1String registryKey("HKEY_LOCAL_MACHINE\\SOFTWARE\\Android Studio"); | 
					
						
							|  |  |  |         const QLatin1String valueName("Path"); | 
					
						
							|  |  |  |     #if defined(Q_OS_WIN)
 | 
					
						
							|  |  |  |         const QSettings settings64(registryKey, QSettings::Registry64Format); | 
					
						
							|  |  |  |         const QSettings settings32(registryKey, QSettings::Registry32Format); | 
					
						
							|  |  |  |         return Utils::FilePath::fromUserInput( | 
					
						
							|  |  |  |                     settings64.value(valueName, settings32.value(valueName).toString()).toString()); | 
					
						
							|  |  |  |     #endif
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return {}; // TODO non-Windows
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-26 00:33:43 +03:00
										 |  |  | FilePath AndroidConfig::getJdkPath() | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-06-26 00:33:43 +03:00
										 |  |  |     FilePath jdkHome; | 
					
						
							| 
									
										
										
										
											2013-04-17 11:52:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-26 00:33:43 +03:00
										 |  |  |     if (HostOsInfo::isWindowsHost()) { | 
					
						
							|  |  |  |         QStringList allVersions; | 
					
						
							|  |  |  |         std::unique_ptr<QSettings> settings( | 
					
						
							|  |  |  |             new QSettings(jdk8SettingsPath, QSettings::NativeFormat)); | 
					
						
							|  |  |  |         allVersions = settings->childGroups(); | 
					
						
							|  |  |  | #ifdef Q_OS_WIN
 | 
					
						
							|  |  |  |         if (allVersions.isEmpty()) { | 
					
						
							|  |  |  |             settings.reset(new QSettings(jdk8SettingsPath, QSettings::Registry64Format)); | 
					
						
							|  |  |  |             allVersions = settings->childGroups(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | #endif // Q_OS_WIN
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // If no jdk 1.8 can be found, look for jdk versions above 1.8
 | 
					
						
							|  |  |  |         // Android section would warn if sdkmanager cannot run with newer jdk versions
 | 
					
						
							|  |  |  |         if (allVersions.isEmpty()) { | 
					
						
							|  |  |  |             settings.reset(new QSettings(jdkLatestSettingsPath, QSettings::NativeFormat)); | 
					
						
							| 
									
										
										
										
											2017-08-08 14:27:54 +02:00
										 |  |  |             allVersions = settings->childGroups(); | 
					
						
							|  |  |  | #ifdef Q_OS_WIN
 | 
					
						
							|  |  |  |             if (allVersions.isEmpty()) { | 
					
						
							| 
									
										
										
										
											2020-06-26 00:33:43 +03:00
										 |  |  |                 settings.reset(new QSettings(jdkLatestSettingsPath, QSettings::Registry64Format)); | 
					
						
							| 
									
										
										
										
											2017-08-08 14:27:54 +02:00
										 |  |  |                 allVersions = settings->childGroups(); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-04-25 13:24:28 +02:00
										 |  |  | #endif // Q_OS_WIN
 | 
					
						
							| 
									
										
										
										
											2020-06-26 00:33:43 +03:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-25 13:24:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-26 00:33:43 +03:00
										 |  |  |         for (const QString &version : allVersions) { | 
					
						
							|  |  |  |             settings->beginGroup(version); | 
					
						
							|  |  |  |             jdkHome = FilePath::fromUserInput(settings->value("JavaHome").toString()); | 
					
						
							|  |  |  |             settings->endGroup(); | 
					
						
							|  |  |  |             if (version.startsWith("1.8")) { | 
					
						
							|  |  |  |                 if (!jdkHome.exists()) | 
					
						
							| 
									
										
										
										
											2013-06-10 18:19:08 +02:00
										 |  |  |                     continue; | 
					
						
							| 
									
										
										
										
											2020-06-26 00:33:43 +03:00
										 |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2013-06-10 18:19:08 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-07-20 15:07:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Nothing found yet? Let's try finding Android Studio's jdk
 | 
					
						
							|  |  |  |         if (jdkHome.isEmpty()) { | 
					
						
							|  |  |  |             const Utils::FilePath androidStudioSdkPath = androidStudioPath(); | 
					
						
							|  |  |  |             if (!androidStudioSdkPath.isEmpty()) { | 
					
						
							|  |  |  |                 const Utils::FilePath androidStudioSdkJrePath = androidStudioSdkPath / "jre"; | 
					
						
							|  |  |  |                 if (androidStudioSdkJrePath.exists()) | 
					
						
							|  |  |  |                     jdkHome = androidStudioSdkJrePath; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-06-26 00:33:43 +03:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         QStringList args; | 
					
						
							|  |  |  |         if (HostOsInfo::isMacHost()) | 
					
						
							|  |  |  |             args << "-c" | 
					
						
							|  |  |  |                  << "/usr/libexec/java_home"; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             args << "-c" | 
					
						
							|  |  |  |                  << "readlink -f $(which java)"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QProcess findJdkPathProc; | 
					
						
							|  |  |  |         findJdkPathProc.start("sh", args); | 
					
						
							|  |  |  |         findJdkPathProc.waitForFinished(); | 
					
						
							|  |  |  |         QByteArray jdkPath = findJdkPathProc.readAllStandardOutput().trimmed(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (HostOsInfo::isMacHost()) { | 
					
						
							|  |  |  |             jdkHome = FilePath::fromUtf8(jdkPath); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             jdkPath.replace("bin/java", ""); // For OpenJDK 11
 | 
					
						
							| 
									
										
										
										
											2020-07-22 10:55:17 +03:00
										 |  |  |             jdkPath.replace("jre", ""); | 
					
						
							|  |  |  |             jdkPath.replace("//", "/"); | 
					
						
							| 
									
										
										
										
											2020-06-26 00:33:43 +03:00
										 |  |  |             jdkHome = FilePath::fromUtf8(jdkPath); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-04-17 11:52:16 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-26 00:33:43 +03:00
										 |  |  |     return jdkHome; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-06-10 18:19:08 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-26 00:33:43 +03:00
										 |  |  | void AndroidConfigurations::load() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSettings *settings = Core::ICore::settings(); | 
					
						
							|  |  |  |     settings->beginGroup(SettingsGroup); | 
					
						
							|  |  |  |     m_config.load(*settings); | 
					
						
							|  |  |  |     settings->endGroup(); | 
					
						
							| 
									
										
										
										
											2013-03-27 15:49:11 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AndroidConfigurations::updateAndroidDevice() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-08-23 09:21:18 +02:00
										 |  |  |     DeviceManager * const devMgr = DeviceManager::instance(); | 
					
						
							| 
									
										
										
										
											2014-10-24 13:15:54 +02:00
										 |  |  |     if (m_instance->m_config.adbToolPath().exists()) | 
					
						
							| 
									
										
										
										
											2019-01-14 18:01:06 +01:00
										 |  |  |         devMgr->addDevice(AndroidDevice::create()); | 
					
						
							| 
									
										
										
										
											2013-04-10 11:05:33 +02:00
										 |  |  |     else if (devMgr->find(Constants::ANDROID_DEVICE_ID)) | 
					
						
							| 
									
										
										
										
											2020-06-26 13:59:38 +02:00
										 |  |  |         devMgr->removeDevice(Utils::Id(Constants::ANDROID_DEVICE_ID)); | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-25 12:19:15 +02:00
										 |  |  | AndroidConfigurations *AndroidConfigurations::m_instance = nullptr; | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-17 13:58:50 +02:00
										 |  |  | QDebug &operator<<(QDebug &stream, const AndroidDeviceInfo &device) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     stream << "Type:"<< (device.type == AndroidDeviceInfo::Emulator ? "Emulator" : "Device") | 
					
						
							|  |  |  |            << ", ABI:" << device.cpuAbi << ", Serial:" << device.serialNumber | 
					
						
							|  |  |  |            << ", Name:" << device.avdname << ", API:" << device.sdk | 
					
						
							|  |  |  |            << ", Authorised:" << !device.unauthorized; | 
					
						
							|  |  |  |     return stream; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:30:57 +03:00
										 |  |  | } // namespace Android
 |