summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAssam Boudjelthia <assam.boudjelthia@qt.io>2021-08-22 01:51:57 +0300
committerAssam Boudjelthia <assam.boudjelthia@qt.io>2021-09-21 15:33:40 +0000
commit96255208a53532906c1b0c3130dc53776efa3a71 (patch)
tree5aa0e851aefbdc542fa5db9cd1c71ab002bab452 /src
parent15b6eaa47b348efaae4756cd2a095dc78273337d (diff)
downloadqt-creator-96255208a53532906c1b0c3130dc53776efa3a71.tar.gz
Change device selection mechanism on Android
Currently, on deploy/debug steps on Android, an AndroidDeviceDialog is popped up each time a deployement is done to select a device. This can be avoidable by using Qt Creator DeviceKitAspect to have the list of devices easily selectable from the project mini-menu. This is better than the current way because it: * reduces the time from deployment to running the app * reduces the number of clicks * avoids having to select the same device each time or * if a default device is selected, this avoids having to go to project settings to reset the default device to be able to deploy to a new device. * it looks cleaner and more compatible with Creator. Task-number: QTCREATORBUG-23991 Change-Id: Ida4ab7245c1a3b0ca26c5ccdc9a21a072edf0725 Reviewed-by: Alessandro Portale <alessandro.portale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/android/CMakeLists.txt1
-rw-r--r--src/plugins/android/android.pro3
-rw-r--r--src/plugins/android/android.qbs3
-rw-r--r--src/plugins/android/androidconfigurations.cpp98
-rw-r--r--src/plugins/android/androidconfigurations.h8
-rw-r--r--src/plugins/android/androidconstants.h11
-rw-r--r--src/plugins/android/androiddeployqtstep.cpp52
-rw-r--r--src/plugins/android/androiddevice.cpp281
-rw-r--r--src/plugins/android/androiddevice.h50
-rw-r--r--src/plugins/android/androiddevicedialog.cpp636
-rw-r--r--src/plugins/android/androiddevicedialog.h88
-rw-r--r--src/plugins/android/androiddevicedialog.ui215
-rw-r--r--src/plugins/android/androidmanager.cpp14
-rw-r--r--src/plugins/android/androidpotentialkit.cpp8
-rw-r--r--src/plugins/android/androidrunner.cpp14
-rw-r--r--src/plugins/projectexplorer/images/MaemoDevice.pngbin976 -> 0 bytes
-rw-r--r--src/plugins/projectexplorer/images/Simulator.pngbin1483 -> 0 bytes
-rw-r--r--src/plugins/projectexplorer/projectexplorer.qrc2
-rw-r--r--src/tools/iconlister/iconlister.cpp4
19 files changed, 417 insertions, 1071 deletions
diff --git a/src/plugins/android/CMakeLists.txt b/src/plugins/android/CMakeLists.txt
index bd63886f9a..12885d3699 100644
--- a/src/plugins/android/CMakeLists.txt
+++ b/src/plugins/android/CMakeLists.txt
@@ -13,7 +13,6 @@ add_qtc_plugin(Android
androiddebugsupport.cpp androiddebugsupport.h
androiddeployqtstep.cpp androiddeployqtstep.h
androiddevice.cpp androiddevice.h
- androiddevicedialog.cpp androiddevicedialog.h androiddevicedialog.ui
androiddeviceinfo.cpp androiddeviceinfo.h
androiderrormessage.cpp androiderrormessage.h
androidextralibrarylistmodel.cpp androidextralibrarylistmodel.h
diff --git a/src/plugins/android/android.pro b/src/plugins/android/android.pro
index 7bdd5539c9..4e0af0ec77 100644
--- a/src/plugins/android/android.pro
+++ b/src/plugins/android/android.pro
@@ -33,7 +33,6 @@ HEADERS += \
androidmanifesteditor.h \
androidmanifesteditorwidget.h \
androidmanifestdocument.h \
- androiddevicedialog.h \
androiddeployqtstep.h \
certificatesmodel.h \
androidpotentialkit.h \
@@ -82,7 +81,6 @@ SOURCES += \
androidmanifesteditor.cpp \
androidmanifesteditorwidget.cpp \
androidmanifestdocument.cpp \
- androiddevicedialog.cpp \
androiddeployqtstep.cpp \
certificatesmodel.cpp \
androidpotentialkit.cpp \
@@ -109,7 +107,6 @@ FORMS += \
androidsettingswidget.ui \
addnewavddialog.ui \
androidcreatekeystorecertificate.ui \
- androiddevicedialog.ui \
androidsdkmanagerwidget.ui
RESOURCES = android.qrc
diff --git a/src/plugins/android/android.qbs b/src/plugins/android/android.qbs
index 7dbe73b1d9..52c67e4503 100644
--- a/src/plugins/android/android.qbs
+++ b/src/plugins/android/android.qbs
@@ -35,9 +35,6 @@ Project {
"androiddeployqtstep.h",
"androiddebugsupport.cpp",
"androiddebugsupport.h",
- "androiddevicedialog.cpp",
- "androiddevicedialog.h",
- "androiddevicedialog.ui",
"androiddevice.cpp",
"androiddevice.h",
"androiddeviceinfo.cpp",
diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp
index ff16e3f0be..f1eb6379d6 100644
--- a/src/plugins/android/androidconfigurations.cpp
+++ b/src/plugins/android/androidconfigurations.cpp
@@ -29,7 +29,6 @@
#include "androiddevice.h"
#include "androidmanager.h"
#include "androidqtversion.h"
-#include "androiddevicedialog.h"
#include "avddialog.h"
#include <coreplugin/icore.h>
@@ -691,6 +690,26 @@ QString AndroidConfig::getAvdName(const QString &serialnumber)
return QString::fromLatin1(name).trimmed();
}
+QStringList AndroidConfig::getRunningAvdsFromDevices(const QVector<AndroidDeviceInfo> &devs)
+{
+ QStringList runningDevs;
+ for (const AndroidDeviceInfo &dev : devs) {
+ if (!dev.serialNumber.startsWith("emulator"))
+ continue;
+ QStringList args = AndroidDeviceInfo::adbSelector(dev.serialNumber);
+ args.append({"emu", "avd", "name"});
+ SdkToolResult result = AndroidManager::runAdbCommand(args);
+ const QString stdOut = result.stdOut();
+ if (stdOut.isEmpty())
+ continue; // Not an avd
+ const QStringList outputLines = stdOut.split('\n');
+ if (outputLines.size() > 1)
+ runningDevs.append(outputLines.first());
+ }
+
+ return runningDevs;
+}
+
AndroidConfig::OpenGl AndroidConfig::getOpenGLEnabled(const QString &emulator) const
{
QDir dir = QDir::home();
@@ -1067,54 +1086,6 @@ void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs)
emit m_instance->updated();
}
-AndroidDeviceInfo AndroidConfigurations::showDeviceDialog(Project *project,
- int apiLevel, const QStringList &abis)
-{
- QString serialNumber;
- for (const QString &abi : abis) {
- serialNumber = defaultDevice(project, abi);
- if (!serialNumber.isEmpty())
- break;
- }
-
- const AndroidDeviceInfo defaultDevice = AndroidDeviceDialog::defaultDeviceInfo(serialNumber);
- if (defaultDevice.isValid())
- return defaultDevice;
-
- AndroidDeviceDialog dialog(apiLevel, abis, serialNumber, Core::ICore::dialogParent());
- AndroidDeviceInfo info = dialog.showAndGetSelectedDevice();
- if (dialog.saveDeviceSelection() && info.isValid()) {
- const QString newSerialNumber = info.type == AndroidDeviceInfo::Hardware ?
- info.serialNumber : info.avdname;
- if (!newSerialNumber.isEmpty()) {
- const QString preferredAbi = AndroidManager::devicePreferredAbi(info.cpuAbi, abis);
- AndroidConfigurations::setDefaultDevice(project, preferredAbi, newSerialNumber);
- }
- }
- return info;
-}
-
-void AndroidConfigurations::clearDefaultDevices(Project *project)
-{
- if (m_instance->m_defaultDeviceForAbi.contains(project))
- m_instance->m_defaultDeviceForAbi.remove(project);
-}
-
-void AndroidConfigurations::setDefaultDevice(Project *project, const QString &abi, const QString &serialNumber)
-{
- 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);
-}
-
static bool matchToolChain(const ToolChain *atc, const ToolChain *btc)
{
if (atc == btc)
@@ -1306,15 +1277,6 @@ void AndroidConfigurations::updateAutomaticKitList()
qtVersionsForArch[qtAbis.first()].append(qtVersion);
}
- DeviceManager *dm = DeviceManager::instance();
- IDevice::ConstPtr device = dm->find(Constants::ANDROID_DEVICE_ID);
- if (device.isNull()) {
- // no device, means no sdk path
- for (Kit *k : existingKits)
- KitManager::deregisterKit(k);
- return;
- }
-
// register new kits
const QList<ToolChain *> toolchains = ToolChainManager::toolChains([](const ToolChain *tc) {
return tc->isAutoDetected()
@@ -1350,20 +1312,20 @@ void AndroidConfigurations::updateAutomaticKitList()
ToolChainKitAspect::cToolChain(b));
});
- const auto initializeKit = [allLanguages, device, tc, qt](Kit *k) {
+ const auto initializeKit = [allLanguages, tc, qt](Kit *k) {
k->setAutoDetected(true);
k->setAutoDetectionSource("AndroidConfiguration");
DeviceTypeKitAspect::setDeviceTypeId(k, Constants::ANDROID_DEVICE_TYPE);
for (ToolChain *tc : allLanguages)
ToolChainKitAspect::setToolChain(k, tc);
QtKitAspect::setQtVersion(k, qt);
- DeviceKitAspect::setDevice(k, device);
QStringList abis = static_cast<const AndroidQtVersion *>(qt)->androidAbis();
Debugger::DebuggerKitAspect::setDebugger(k, findOrRegisterDebugger(tc, abis));
k->setSticky(ToolChainKitAspect::id(), true);
k->setSticky(QtKitAspect::id(), true);
k->setSticky(DeviceKitAspect::id(), true);
+ k->setMutable(DeviceKitAspect::id(), true);
k->setSticky(DeviceTypeKitAspect::id(), true);
QString versionStr = QLatin1String("Qt %{Qt:Version}");
@@ -1433,14 +1395,10 @@ AndroidConfigurations::AndroidConfigurations()
: m_sdkManager(new AndroidSdkManager(m_config))
{
load();
-
- connect(SessionManager::instance(), &SessionManager::projectRemoved,
- this, &AndroidConfigurations::clearDefaultDevices);
connect(DeviceManager::instance(), &DeviceManager::devicesLoaded,
this, &AndroidConfigurations::updateAndroidDevice);
m_force32bit = is32BitUserSpace();
-
m_instance = this;
}
@@ -1545,11 +1503,13 @@ void AndroidConfigurations::load()
void AndroidConfigurations::updateAndroidDevice()
{
- DeviceManager * const devMgr = DeviceManager::instance();
- if (m_instance->m_config.adbToolPath().exists())
- devMgr->addDevice(AndroidDevice::create());
- else if (devMgr->find(Constants::ANDROID_DEVICE_ID))
- devMgr->removeDevice(Constants::ANDROID_DEVICE_ID);
+ // Remove any dummy Android device, because it won't be usable.
+ DeviceManager *const devMgr = DeviceManager::instance();
+ IDevice::ConstPtr dev = devMgr->find(Constants::ANDROID_DEVICE_ID);
+ if (dev)
+ devMgr->removeDevice(dev->id());
+
+ AndroidDeviceManager::instance()->setupDevicesWatcher();
}
AndroidConfigurations *AndroidConfigurations::m_instance = nullptr;
diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h
index dc9d3fd6be..7071fe5357 100644
--- a/src/plugins/android/androidconfigurations.h
+++ b/src/plugins/android/androidconfigurations.h
@@ -171,6 +171,8 @@ public:
static Utils::FilePath getJdkPath();
+ static QStringList getRunningAvdsFromDevices(const QVector<AndroidDeviceInfo> &devs);
+
private:
static QString getDeviceProperty(const Utils::FilePath &adbToolPath,
const QString &device, const QString &property);
@@ -213,10 +215,6 @@ public:
static void setConfig(const AndroidConfig &config);
static AndroidConfigurations *instance();
- static AndroidDeviceInfo showDeviceDialog(ProjectExplorer::Project *project, int apiLevel, const QStringList &abis);
- static void setDefaultDevice(ProjectExplorer::Project *project, const QString &abi, const QString &serialNumber); // serial number or avd name
- static QString defaultDevice(ProjectExplorer::Project *project, const QString &abi); // serial number or avd name
- static void clearDefaultDevices(ProjectExplorer::Project *project);
static void registerNewToolChains();
static void registerCustomToolChainsAndDebuggers();
static void removeUnusedDebuggers();
@@ -240,8 +238,6 @@ private:
static AndroidConfigurations *m_instance;
AndroidConfig m_config;
std::unique_ptr<Internal::AndroidSdkManager> m_sdkManager;
-
- QMap<ProjectExplorer::Project *, QMap<QString, QString> > m_defaultDeviceForAbi;
bool m_force32bit;
};
diff --git a/src/plugins/android/androidconstants.h b/src/plugins/android/androidconstants.h
index 01350cd718..df8c821f98 100644
--- a/src/plugins/android/androidconstants.h
+++ b/src/plugins/android/androidconstants.h
@@ -26,6 +26,7 @@
#pragma once
#include <QtGlobal>
+#include <utils/id.h>
namespace Android {
namespace Internal {
@@ -93,5 +94,15 @@ const char NdkLocation[] = "NdkLocation"; // FileName
const char SdkLocation[] = "SdkLocation"; // FileName
const char AndroidABIs[] = "AndroidABIs"; // QString
+// Android Device
+const Utils::Id AndroidSerialNumber = "AndroidSerialNumber";
+const Utils::Id AndroidAvdName = "AndroidAvdName";
+const Utils::Id AndroidCpuAbi = "AndroidCpuAbi";
+const Utils::Id AndroidAvdTarget = "AndroidAvdTarget";
+const Utils::Id AndroidAvdDevice = "AndroidAvdDevice";
+const Utils::Id AndroidAvdSkin = "AndroidAvdSkin";
+const Utils::Id AndroidAvdSdcard = "AndroidAvdSdcard";
+const Utils::Id AndroidSdk = "AndroidSdk";
+
} // namespace Constants;
} // namespace Android
diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp
index 9e9c85b70f..12d3b3e651 100644
--- a/src/plugins/android/androiddeployqtstep.cpp
+++ b/src/plugins/android/androiddeployqtstep.cpp
@@ -33,6 +33,7 @@
#include "androidglobal.h"
#include "androidavdmanager.h"
#include "androidqtversion.h"
+#include "androiddevice.h"
#include <coreplugin/fileutils.h>
#include <coreplugin/icore.h>
@@ -147,14 +148,6 @@ bool AndroidDeployQtStep::init()
if (androidDeployQtStep != this)
info = androidDeployQtStep->m_deviceInfo;
- if (!info.isValid()) {
- info = AndroidConfigurations::showDeviceDialog(project(), minTargetApi, m_androidABIs);
- m_deviceInfo = info; // Keep around for later steps
- }
-
- if (!info.isValid()) // aborted
- return false;
-
const BuildSystem *bs = buildSystem();
auto selectedAbis = bs->property(Constants::ANDROID_ABIS).toStringList();
@@ -165,6 +158,40 @@ bool AndroidDeployQtStep::init()
if (selectedAbis.isEmpty())
selectedAbis.append(bs->extraData(buildKey, Constants::AndroidArch).toString());
+ if (!info.isValid()) {
+ const IDevice *dev = DeviceKitAspect::device(kit()).data();
+ info = AndroidDevice::androidDeviceInfoFromIDevice(dev);
+ m_deviceInfo = info; // Keep around for later steps
+
+ if (!info.isValid()) {
+ const QString error = tr("The deployment device \"%1\" is invalid.")
+ .arg(dev->displayName());
+ emit addOutput(error, OutputFormat::Stderr);
+ TaskHub::addTask(DeploymentTask(Task::Error, error));
+ return false;
+ }
+
+ const AndroidDevice *androidDev = static_cast<const AndroidDevice *>(dev);
+ if (androidDev && !androidDev->canSupportAbis(selectedAbis)) {
+ const QString error = tr("The deployment device \"%1\" doesn't support the "
+ "architectures used by the kit.\n"
+ "The kit supports \"%2\", but the device uses \"%3\".")
+ .arg(dev->displayName()).arg(selectedAbis.join(", "))
+ .arg(androidDev->supportedAbis().join(", "));
+ emit addOutput(error, OutputFormat::Stderr);
+ TaskHub::addTask(DeploymentTask(Task::Error, error));
+ return false;
+ }
+
+ if (androidDev && !androidDev->canHandleDeployments()) {
+ const QString error = tr("The deployment device \"%1\" is disconnected.")
+ .arg(dev->displayName());
+ emit addOutput(error, OutputFormat::Stderr);
+ TaskHub::addTask(DeploymentTask(Task::Error, error));
+ return false;
+ }
+ }
+
const QtSupport::BaseQtVersion * const qt = QtSupport::QtKitAspect::qtVersion(kit());
if (qt && qt->supportsMultipleQtAbis() && !selectedAbis.contains(info.cpuAbi.first())) {
TaskHub::addTask(DeploymentTask(
@@ -500,14 +527,6 @@ void AndroidDeployQtStep::runCommand(const CommandLine &command)
QWidget *AndroidDeployQtStep::createConfigWidget()
{
auto widget = new QWidget;
-
- auto resetDefaultDevices = new QPushButton(widget);
- resetDefaultDevices->setText(tr("Reset Default Deployment Devices"));
-
- connect(resetDefaultDevices, &QAbstractButton::clicked, this, [this] {
- AndroidConfigurations::clearDefaultDevices(project());
- });
-
auto installCustomApkButton = new QPushButton(widget);
installCustomApkButton->setText(tr("Install an APK File"));
@@ -523,7 +542,6 @@ QWidget *AndroidDeployQtStep::createConfigWidget()
Layouting::Form builder;
builder.addRow(m_uninstallPreviousPackage);
- builder.addRow(resetDefaultDevices);
builder.addRow(installCustomApkButton);
builder.attachTo(widget);
diff --git a/src/plugins/android/androiddevice.cpp b/src/plugins/android/androiddevice.cpp
index 16ff682824..6c24978b53 100644
--- a/src/plugins/android/androiddevice.cpp
+++ b/src/plugins/android/androiddevice.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2021 The Qt Company Ltd.
** Copyright (C) 2016 BogDan Vatra <bog_dan_ro@yahoo.com>
** Contact: https://www.qt.io/licensing/
**
@@ -24,19 +25,29 @@
****************************************************************************/
#include "androiddevice.h"
+
+#include "androidavdmanager.h"
+#include "androidconfigurations.h"
#include "androidconstants.h"
#include "androidsignaloperation.h"
-#include "androidconfigurations.h"
-#include "androidmanager.h"
+#include <projectexplorer/devicesupport/devicemanager.h>
#include <projectexplorer/runconfiguration.h>
#include <utils/url.h>
+#include <utils/runextensions.h>
#include <QLoggingCategory>
using namespace ProjectExplorer;
+namespace {
+static Q_LOGGING_CATEGORY(androidDeviceLog, "qtc.android.androiddevice", QtWarningMsg)
+}
+
+// interval for updating the list of connected Android devices and emulators
+constexpr int deviceUpdaterMsInterval = 30000;
+
namespace Android {
namespace Internal {
@@ -48,8 +59,151 @@ AndroidDevice::AndroidDevice()
setDisplayType(tr("Android"));
setMachineType(IDevice::Hardware);
setOsType(Utils::OsTypeOtherUnix);
+ setDeviceState(DeviceConnected);
+
+ addDeviceAction({tr("Refresh"), [](const IDevice::Ptr &device, QWidget *parent) {
+ AndroidDeviceManager::instance()->updateDevicesListOnce();
+ }});
+}
+
+IDevice::Ptr AndroidDevice::create()
+{
+ return IDevice::Ptr(new AndroidDevice);
+}
+
+AndroidDeviceInfo AndroidDevice::androidDeviceInfoFromIDevice(const IDevice *dev)
+{
+ AndroidDeviceInfo info;
+ AndroidDeviceInfo::State state;
+ if (dev->deviceState() == IDevice::DeviceReadyToUse)
+ state = AndroidDeviceInfo::OkState;
+ else if (dev->deviceState() == IDevice::DeviceDisconnected)
+ state = AndroidDeviceInfo::OfflineState;
+ else if (dev->deviceState() == IDevice::DeviceConnected)
+ state = AndroidDeviceInfo::UnAuthorizedState;
+ info.state = state;
+ info.avdname = dev->extraData(Constants::AndroidAvdName).toString();
+ info.serialNumber = dev->extraData(Constants::AndroidSerialNumber).toString();
+ info.cpuAbi = dev->extraData(Constants::AndroidCpuAbi).toStringList();
+ info.avdTarget = dev->extraData(Constants::AndroidAvdTarget).toString();
+ info.avdDevice = dev->extraData(Constants::AndroidAvdDevice).toString();
+ info.avdSkin = dev->extraData(Constants::AndroidAvdSkin).toString();
+ info.avdSdcardSize = dev->extraData(Constants::AndroidAvdSdcard).toString();
+ info.sdk = dev->extraData(Constants::AndroidSdk).toInt();
+ info.type = (dev->machineType() == ProjectExplorer::IDevice::Hardware
+ ? AndroidDeviceInfo::Hardware : AndroidDeviceInfo::Emulator);
+
+ return info;
+}
+
+void AndroidDevice::setAndroidDeviceInfoExtras(IDevice *dev, const AndroidDeviceInfo &info)
+{
+ dev->setMachineType(info.type == AndroidDeviceInfo::Hardware
+ ? ProjectExplorer::IDevice::Hardware
+ : ProjectExplorer::IDevice::Emulator);
+ dev->setDeviceState(deviceStateFromInfo(info.state));
+ dev->setExtraData(Constants::AndroidAvdName, info.avdname);
+ dev->setExtraData(Constants::AndroidSerialNumber, info.serialNumber);
+ dev->setExtraData(Constants::AndroidCpuAbi, info.cpuAbi);
+ dev->setExtraData(Constants::AndroidAvdTarget, info.avdTarget);
+ dev->setExtraData(Constants::AndroidAvdDevice, info.avdDevice);
+ dev->setExtraData(Constants::AndroidAvdSkin, info.avdSkin);
+ dev->setExtraData(Constants::AndroidAvdSdcard, info.avdSdcardSize);
+ dev->setExtraData(Constants::AndroidSdk, info.sdk);
+}
+
+QString AndroidDevice::displayNameFromInfo(const AndroidDeviceInfo &info)
+{
+ return info.type == AndroidDeviceInfo::Hardware
+ ? AndroidConfigurations::currentConfig().getProductModel(info.serialNumber)
+ : info.avdname;
+}
+
+Utils::Id AndroidDevice::idFromDeviceInfo(const AndroidDeviceInfo &info)
+{
+ const QString id = (info.type == AndroidDeviceInfo::Hardware ? info.serialNumber
+ : info.avdname);
+ return Utils::Id(Constants::ANDROID_DEVICE_ID).withSuffix(':' + id);
+}
+
+Utils::Id AndroidDevice::idFromAvdInfo(const CreateAvdInfo &info)
+{
+ return Utils::Id(Constants::ANDROID_DEVICE_ID).withSuffix(':' + info.name);
+}
+
+IDevice::DeviceState AndroidDevice::deviceStateFromInfo(AndroidDeviceInfo::State state)
+{
+ if (state == AndroidDeviceInfo::OkState)
+ return IDevice::DeviceReadyToUse;
+ if (state == AndroidDeviceInfo::OfflineState)
+ return IDevice::DeviceDisconnected;
+ return IDevice::DeviceConnected;
+}
+
+QStringList AndroidDevice::supportedAbis() const
+{
+ return extraData(Constants::AndroidCpuAbi).toStringList();
+}
+
+bool AndroidDevice::canSupportAbis(const QStringList &abis) const
+{
+ // If the list is empty, no valid decision can be made, this means something is wrong
+ // somewhere, but let's not stop deployment.
+ QTC_ASSERT(!abis.isEmpty(), return true);
+
+ const QStringList ourAbis = supportedAbis();
+ QTC_ASSERT(!ourAbis.isEmpty(), return false);
+
+ for (const QString &abi : abis)
+ if (ourAbis.contains(abi))
+ return true; // it's enough if only one abi match is found
+
+ // If no exact match is found, let's take ABI backward compatibility into account
+ // https://developer.android.com/ndk/guides/abis#android-platform-abi-support
+ // arm64 usually can run {arm, armv7}, x86 can support {arm, armv7}, and 64-bit devices
+ // can support their 32-bit variants.
+ using namespace ProjectExplorer::Constants;
+ const bool isTheirsArm = abis.contains(ANDROID_ABI_ARMEABI_V7A)
+ || abis.contains(ANDROID_ABI_ARMEABI_V7A);
+ // The primary ABI at the first index
+ const bool oursSupportsArm = ourAbis.first() == ANDROID_ABI_ARM64_V8A
+ || ourAbis.first() == ANDROID_ABI_X86;
+ // arm64 and x86 can run armv7 and arm
+ if (isTheirsArm && oursSupportsArm)
+ return true;
+ // x64 can run x86
+ if (ourAbis.first() == ANDROID_ABI_X86_64 && abis.contains(ANDROID_ABI_X86))
+ return true;
+
+ return false;
+}
- setDeviceState(DeviceReadyToUse);
+bool AndroidDevice::canHandleDeployments() const
+{
+ // If hardware and disconned, it wouldn't be possilbe to start it, unlike an emulator
+ if (machineType() == Hardware && deviceState() == DeviceDisconnected)
+ return false;
+ return true;
+}
+
+bool AndroidDevice::isValid() const
+{
+ return !serialNumber().isEmpty() || !avdName().isEmpty();
+}
+
+QString AndroidDevice::serialNumber() const
+{
+ return extraData(Constants::AndroidSerialNumber).toString();
+}
+
+QString AndroidDevice::avdName() const
+{
+ return extraData(Constants::AndroidAvdName).toString();
+}
+
+int AndroidDevice::sdkLevel() const
+{
+ return extraData(Constants::AndroidSdk).toInt();
}
IDevice::DeviceInfo AndroidDevice::deviceInformation() const
@@ -80,9 +234,128 @@ QUrl AndroidDevice::toolControlChannel(const ControlChannelHint &) const
return url;
}
+void AndroidDeviceManager::updateDevicesList()
+{
+ connect(&m_devicesUpdaterTimer, &QTimer::timeout, this, [this]() {
+ updateDevicesListOnce();
+ });
+ updateDevicesListOnce();
+ m_devicesUpdaterTimer.start(deviceUpdaterMsInterval);
+}
+
+void AndroidDeviceManager::updateDevicesListOnce()
+{
+ if (!m_avdsFutureWatcher.isRunning() && m_androidConfig.adbToolPath().exists()) {
+ m_avdsFutureWatcher.setFuture((new AndroidAvdManager)->avdList());
+ m_devicesFutureWatcher.setFuture(Utils::runAsync([this]() {
+ return m_androidConfig.connectedDevices();
+ }));
+ }
+}
-// Factory
+void AndroidDeviceManager::setupDevicesWatcher()
+{
+ // The call to avdmanager is always slower than the call to adb devices,
+ // so connecting the slot to the slower call should be enough.
+ connect(&m_avdsFutureWatcher, &QFutureWatcherBase::finished,
+ this, &AndroidDeviceManager::devicesListUpdated);
+ updateDevicesList();
+}
+
+void AndroidDeviceManager::devicesListUpdated()
+{
+ QVector<AndroidDeviceInfo> connectedDevicesInfos;
+ connectedDevicesInfos = m_devicesFutureWatcher.result();
+
+ // For checking the state of avds, since running avds are assigned a serial number of
+ // the form emulator-xxxx, thus we have to manually check for the names.
+ const QStringList runningAvds = m_androidConfig.getRunningAvdsFromDevices(connectedDevicesInfos);
+
+ AndroidDeviceInfoList devices = m_avdsFutureWatcher.result();
+ const QSet<QString> startedAvds = Utils::transform<QSet>(connectedDevicesInfos,
+ &AndroidDeviceInfo::avdname);
+ for (const AndroidDeviceInfo &dev : devices)
+ if (!startedAvds.contains(dev.avdname))
+ connectedDevicesInfos << dev;
+
+ DeviceManager *const devMgr = DeviceManager::instance();
+
+ QVector<IDevice::ConstPtr> existingDevs;
+ QVector<IDevice::ConstPtr> connectedDevs;
+
+ for (int i = 0; i < devMgr->deviceCount(); ++i) {
+ const IDevice::ConstPtr dev = devMgr->deviceAt(i);
+ if (dev->id().toString().startsWith(Constants::ANDROID_DEVICE_ID)) {
+ existingDevs.append(dev);
+ }
+ }
+
+ for (auto item : connectedDevicesInfos) {
+ const Utils::Id deviceId = AndroidDevice::idFromDeviceInfo(item);
+ const QString displayName = AndroidDevice::displayNameFromInfo(item);
+ IDevice::ConstPtr dev = devMgr->find(deviceId);
+ if (!dev.isNull()) {
+ if (dev->displayName() == displayName) {
+ IDevice::DeviceState newState;
+ // If an AVD is not already running set its state to Connected instead of
+ // ReadyToUse.
+ if (dev->machineType() == IDevice::Emulator && !runningAvds.contains(displayName))
+ newState = IDevice::DeviceConnected;
+ else
+ newState = AndroidDevice::deviceStateFromInfo(item.state);
+ if (dev->deviceState() != newState) {
+ qCDebug(androidDeviceLog, "Device id \"%s\" changed its state.",
+ dev->id().toString().toUtf8().data());
+ devMgr->setDeviceState(dev->id(), newState);
+ }
+ connectedDevs.append(dev);
+ continue;
+ } else {
+ // DeviceManager doens't seem to hav a way to directly update the name, if the name
+ // of the device has changed, remove it and register it again with the new name.
+ devMgr->removeDevice(dev->id());
+ }
+ }
+ AndroidDevice *newDev = new AndroidDevice();
+ newDev->setupId(IDevice::AutoDetected, deviceId);
+ newDev->setDisplayName(displayName);
+ AndroidDevice::setAndroidDeviceInfoExtras(newDev, item);
+ qCDebug(androidDeviceLog, "Registering new Android device id \"%s\".",
+ newDev->id().toString().toUtf8().data());
+ const IDevice::ConstPtr constNewDev = IDevice::ConstPtr(newDev);
+ devMgr->addDevice(constNewDev);
+ connectedDevs.append(constNewDev);
+ }
+
+ // Set devices no longer connected to disconnected state.
+ for (const IDevice::ConstPtr dev : existingDevs) {
+ if (dev->id() != Constants::ANDROID_DEVICE_ID && !connectedDevs.contains(dev)
+ && dev->deviceState() != IDevice::DeviceDisconnected) {
+ qCDebug(androidDeviceLog, "Device id \"%s\" is no longer connected.",
+ dev->id().toString().toUtf8().data());
+ devMgr->setDeviceState(dev->id(), IDevice::DeviceDisconnected);
+ }
+ }
+}
+
+AndroidDeviceManager *AndroidDeviceManager::instance()
+{
+ static AndroidDeviceManager obj;
+ return &obj;
+}
+
+AndroidDeviceManager::AndroidDeviceManager(QObject *parent)
+ : m_androidConfig(AndroidConfigurations::currentConfig())
+{
+ connect(qApp, &QCoreApplication::aboutToQuit, this, [this]() {
+ m_devicesUpdaterTimer.stop();
+ m_avdsFutureWatcher.waitForFinished();
+ m_devicesFutureWatcher.waitForFinished();
+ });
+}
+
+// Factory
AndroidDeviceFactory::AndroidDeviceFactory()
: ProjectExplorer::IDeviceFactory(Constants::ANDROID_DEVICE_TYPE)
{
diff --git a/src/plugins/android/androiddevice.h b/src/plugins/android/androiddevice.h
index 4fea1956c3..b221522307 100644
--- a/src/plugins/android/androiddevice.h
+++ b/src/plugins/android/androiddevice.h
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2021 The Qt Company Ltd.
** Copyright (C) 2016 BogDan Vatra <bog_dan_ro@yahoo.com>
** Contact: https://www.qt.io/licensing/
**
@@ -25,9 +26,15 @@
#pragma once
+#include "androidconfigurations.h"
+#include "androiddeviceinfo.h"
+
#include <projectexplorer/devicesupport/idevice.h>
#include <projectexplorer/devicesupport/idevicefactory.h>
+#include <QFutureWatcher>
+#include <QTimer>
+
namespace Android {
namespace Internal {
@@ -36,17 +43,32 @@ class AndroidDevice final : public ProjectExplorer::IDevice
Q_DECLARE_TR_FUNCTIONS(Android::Internal::AndroidDevice)
public:
- static IDevice::Ptr create() { return IDevice::Ptr(new AndroidDevice); }
-
-private:
AndroidDevice();
- ProjectExplorer::IDevice::DeviceInfo deviceInformation() const override;
+ static IDevice::Ptr create();
+ static AndroidDeviceInfo androidDeviceInfoFromIDevice(const IDevice *dev);
+ static void setAndroidDeviceInfoExtras(IDevice *dev, const AndroidDeviceInfo &info);
+ static QString displayNameFromInfo(const AndroidDeviceInfo &info);
+ static Utils::Id idFromDeviceInfo(const AndroidDeviceInfo &info);
+ static Utils::Id idFromAvdInfo(const CreateAvdInfo &info);
+ static IDevice::DeviceState deviceStateFromInfo(AndroidDeviceInfo::State state);
+
+ QStringList supportedAbis() const;
+ bool canSupportAbis(const QStringList &abis) const;
+
+ bool canHandleDeployments() const;
+
+ bool isValid() const;
+ QString serialNumber() const;
+ QString avdName() const;
+ int sdkLevel() const;
+
+private:
+ ProjectExplorer::IDevice::DeviceInfo deviceInformation() const override;
ProjectExplorer::IDeviceWidget *createWidget() override;
bool canAutoDetectPorts() const override;
ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const override;
-
QUrl toolControlChannel(const ControlChannelHint &) const override;
};
@@ -56,5 +78,23 @@ public:
AndroidDeviceFactory();
};
+class AndroidDeviceManager : public QObject
+{
+public:
+ static AndroidDeviceManager *instance();
+ void setupDevicesWatcher();
+ void updateDevicesList();
+ void updateDevicesListOnce();
+
+private:
+ AndroidDeviceManager(QObject *parent = nullptr);
+ void devicesListUpdated();
+
+ QFutureWatcher<AndroidDeviceInfoList> m_avdsFutureWatcher;
+ QFutureWatcher<QVector<AndroidDeviceInfo>> m_devicesFutureWatcher;
+ QTimer m_devicesUpdaterTimer;
+ AndroidConfig m_androidConfig;
+};
+
} // namespace Internal
} // namespace Android
diff --git a/src/plugins/android/androiddevicedialog.cpp b/src/plugins/android/androiddevicedialog.cpp
deleted file mode 100644
index 9e33808ebb..0000000000
--- a/src/plugins/android/androiddevicedialog.cpp
+++ /dev/null
@@ -1,636 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and 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.
-**
-** 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.
-**
-****************************************************************************/
-
-#include "androiddevicedialog.h"
-#include "androidmanager.h"
-#include "androidavdmanager.h"
-#include "avddialog.h"
-#include "ui_androiddevicedialog.h"
-
-#include <utils/environment.h>
-#include <utils/progressindicator.h>
-#include <utils/algorithm.h>
-
-#include <QMessageBox>
-#include <QPainter>
-#include <QStyledItemDelegate>
-#include <QToolTip>
-
-using namespace Android;
-using namespace Android::Internal;
-
-namespace Android {
-namespace Internal {
-
-QVector<AndroidDeviceInfo> AndroidDeviceDialog::m_connectedDevices = {};
-
-// yeah, writing tree models is fun!
-class AndroidDeviceModelNode
-{
-public:
- AndroidDeviceModelNode(AndroidDeviceModelNode *parent, const AndroidDeviceInfo &info, const QString &incompatibleReason = QString())
- : m_parent(parent), m_info(info), m_incompatibleReason(incompatibleReason)
- {
- if (m_parent)
- m_parent->m_children.append(this);
- }
-
- AndroidDeviceModelNode(AndroidDeviceModelNode *parent, const QString &displayName)
- : m_parent(parent), m_displayName(displayName)
- {
- if (m_parent)
- m_parent->m_children.append(this);
- }
-
- ~AndroidDeviceModelNode()
- {
- if (m_parent)
- m_parent->m_children.removeOne(this);
- QList<AndroidDeviceModelNode *> children = m_children;
- qDeleteAll(children);
- }
-
- AndroidDeviceModelNode *parent() const
- {
- return m_parent;
- }
-
- QList<AndroidDeviceModelNode *> children() const
- {
- return m_children;
- }
-
- AndroidDeviceInfo deviceInfo() const
- {
- return m_info;
- }
-
- QString displayName() const
- {
- return m_displayName;
- }
-
- QString incompatibleReason() const
- {
- return m_incompatibleReason;
- }
-
-private:
- AndroidDeviceModelNode *m_parent;
- AndroidDeviceInfo m_info;
- QString m_incompatibleReason;
- QString m_displayName;
- QList<AndroidDeviceModelNode *> m_children;
-};
-
-class AndroidDeviceModelDelegate : public QStyledItemDelegate
-{
- Q_OBJECT
-public:
- AndroidDeviceModelDelegate(QObject * parent = nullptr)
- : QStyledItemDelegate(parent)
- {
-
- }
-
- ~AndroidDeviceModelDelegate() override = default;
-
- void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
- {
- QStyleOptionViewItem opt = option;
- initStyleOption(&opt, index);
- painter->save();
-
- auto node = static_cast<AndroidDeviceModelNode *>(index.internalPointer());
- AndroidDeviceInfo device = node->deviceInfo();
-
- painter->setPen(Qt::NoPen);
-
- // Paint Background
- QPalette palette = opt.palette; // we always draw enabled
- palette.setCurrentColorGroup(QPalette::Active);
- bool selected = opt.state & QStyle::State_Selected;
- QColor backgroundColor = selected ? palette.highlight().color()
- : palette.window().color();
- painter->setBrush(backgroundColor);
-
- painter->drawRect(0, opt.rect.top(), opt.rect.width() + opt.rect.left(), opt.rect.height());
-
- QColor textColor;
- // Set Text Color
- if (opt.state & QStyle::State_Selected)
- textColor = palette.highlightedText().color();
- else
- textColor = palette.text().color();
- painter->setPen(textColor);
-
- if (!node->displayName().isEmpty()) { // Title
- // We have a top level node
- QFont font = opt.font;
- font.setPointSizeF(font.pointSizeF() * 1.2);
- font.setBold(true);
-
- QFontMetrics fm(font);
- painter->setFont(font);
- int top = (opt.rect.bottom() + opt.rect.top() - fm.height()) / 2 + fm.ascent();
- painter->drawText(6, top, node->displayName());
- } else {
- QIcon icon(device.type == AndroidDeviceInfo::Hardware ? QLatin1String(":/projectexplorer/images/MaemoDevice.png")
- : QLatin1String(":/projectexplorer/images/Simulator.png"));
- int size = opt.rect.bottom() - opt.rect.top() - 12;
- QPixmap pixmap = icon.pixmap(size, size);
- painter->drawPixmap(6 + (size - pixmap.width()) / 2, opt.rect.top() + 6 + (size - pixmap.width()) / 2, pixmap);
-
- QFontMetrics fm(opt.font);
- // TopLeft
- QString topLeft;
- if (device.type == AndroidDeviceInfo::Hardware)
- topLeft = AndroidConfigurations::currentConfig().getProductModel(device.serialNumber);
- else
- topLeft = device.avdname;
- painter->drawText(size + 12, 2 + opt.rect.top() + fm.ascent(), topLeft);
-
-
- // topRight
- auto drawTopRight = [&](const QString text, const QFontMetrics &fm) {
- painter->drawText(opt.rect.right() - fm.horizontalAdvance(text) - 6 , 2 + opt.rect.top() + fm.ascent(), text);
- };
-
- if (device.type == AndroidDeviceInfo::Hardware) {
- drawTopRight(device.serialNumber, fm);
- } else {
- AndroidConfig::OpenGl openGl = AndroidConfigurations::currentConfig().getOpenGLEnabled(device.avdname);
- if (openGl == AndroidConfig::OpenGl::Enabled) {
- drawTopRight(tr("OpenGL enabled"), fm);
- } else if (openGl == AndroidConfig::OpenGl::Disabled) {
- QFont font = painter->font();
- font.setBold(true);
- painter->setFont(font);
- QFontMetrics fmBold(font);
- drawTopRight(tr("OpenGL disabled"), fmBold);
- font.setBold(false);
- painter->setFont(font);
- }
- }
-
- // Directory
- QColor mix;
- mix.setRgbF(0.7 * textColor.redF() + 0.3 * backgroundColor.redF(),
- 0.7 * textColor.greenF() + 0.3 * backgroundColor.greenF(),
- 0.7 * textColor.blueF() + 0.3 * backgroundColor.blueF());
- painter->setPen(mix);
-
- QString lineText;
- if (node->incompatibleReason().isEmpty()) {
- lineText = AndroidManager::androidNameForApiLevel(device.sdk) + QLatin1String(" ");
- lineText += AndroidDeviceDialog::tr("ABI:") + device.cpuAbi.join(QLatin1Char(' '));
- } else {
- lineText = node->incompatibleReason();
- QFont f = painter->font();
- f.setBold(true);
- painter->setFont(f);
- }
- painter->drawText(size + 12, opt.rect.top() + fm.ascent() + fm.height() + 6, lineText);
- }
-
- // Separator lines
- painter->setPen(QColor::fromRgb(150,150,150));
- painter->drawLine(0, opt.rect.bottom(), opt.rect.right(), opt.rect.bottom());
- painter->restore();
- }
-
- QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
- {
- QStyleOptionViewItem opt = option;
- initStyleOption(&opt, index);
-
- QFontMetrics fm(option.font);
- QSize s;
- s.setWidth(option.rect.width());
- s.setHeight(fm.height() * 2 + 10);
- return s;
- }
-};
-
-class AndroidDeviceModel : public QAbstractItemModel
-{
- Q_OBJECT
-public:
- AndroidDeviceModel(int apiLevel, const QStringList &abis);
- QModelIndex index(int row, int column,
- const QModelIndex &parent = QModelIndex()) const override;
- QModelIndex parent(const QModelIndex &child) const override;
- int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- int columnCount(const QModelIndex &parent = QModelIndex()) const override;
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
- Qt::ItemFlags flags(const QModelIndex &index) const override;
-
- AndroidDeviceInfo device(QModelIndex index);
- void setDevices(const QVector<AndroidDeviceInfo> &devices);
-
- QModelIndex indexFor(AndroidDeviceInfo::AndroidDeviceType type, const QString &serial);
-private:
- int m_apiLevel;
- QStringList m_abis;
- AndroidDeviceModelNode *m_root;
-};
-
-}
-}
-/////////////////
-// AndroidDeviceModel
-/////////////////
-AndroidDeviceModel::AndroidDeviceModel(int apiLevel, const QStringList &abis)
- : m_apiLevel(apiLevel), m_abis(abis), m_root(nullptr)
-{
-}
-
-QModelIndex AndroidDeviceModel::index(int row, int column, const QModelIndex &parent) const
-{
- if (column != 0)
- return QModelIndex();
-
- if (!m_root)
- return QModelIndex();
-
- if (!parent.isValid()) {
- if (row < 0 || row >= m_root->children().count())
- return QModelIndex();
- return createIndex(row, column, m_root->children().at(row));
- }
-
- auto node = static_cast<AndroidDeviceModelNode *>(parent.internalPointer());
- if (row < node->children().count())
- return createIndex(row, column, node->children().at(row));
-
- return QModelIndex();
-}
-
-QModelIndex AndroidDeviceModel::parent(const QModelIndex &child) const
-{
- if (!child.isValid())
- return QModelIndex();
- if (!m_root)
- return QModelIndex();
- auto node = static_cast<AndroidDeviceModelNode *>(child.internalPointer());
- if (node == m_root)
- return QModelIndex();
- AndroidDeviceModelNode *parent = node->parent();
-
- if (parent == m_root)
- return QModelIndex();
-
- AndroidDeviceModelNode *grandParent = parent->parent();
- return createIndex(grandParent->children().indexOf(parent), 0, parent);
-}
-
-int AndroidDeviceModel::rowCount(const QModelIndex &parent) const
-{
- if (!m_root)
- return 0;
- if (!parent.isValid())
- return m_root->children().count();
- auto node = static_cast<AndroidDeviceModelNode *>(parent.internalPointer());
- return node->children().count();
-}
-
-int AndroidDeviceModel::columnCount(const QModelIndex &parent) const
-{
- Q_UNUSED(parent)
- return 1;
-}
-
-QVariant AndroidDeviceModel::data(const QModelIndex &index, int role) const
-{
- if (role != Qt::DisplayRole)
- return QVariant();
- auto node = static_cast<AndroidDeviceModelNode *>(index.internalPointer());
- if (!node)
- return QVariant();
- return node->deviceInfo().serialNumber;
-}
-
-Qt::ItemFlags AndroidDeviceModel::flags(const QModelIndex &index) const
-{
- auto node = static_cast<AndroidDeviceModelNode *>(index.internalPointer());
- if (node)
- if (node->displayName().isEmpty() && node->incompatibleReason().isEmpty())
- return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
-
- return Qt::NoItemFlags;
-}
-
-AndroidDeviceInfo AndroidDeviceModel::device(QModelIndex index)
-{
- auto node = static_cast<AndroidDeviceModelNode *>(index.internalPointer());
- if (!node)
- return AndroidDeviceInfo();
- return node->deviceInfo();
-}
-
-void AndroidDeviceModel::setDevices(const QVector<AndroidDeviceInfo> &devices)
-{
- beginResetModel();
- delete m_root;
- m_root = new AndroidDeviceModelNode(nullptr, QString());
-
- AndroidDeviceModelNode *compatibleDevices = new AndroidDeviceModelNode(m_root, AndroidDeviceDialog::tr("Compatible devices"));
- AndroidDeviceModelNode *incompatibleDevices = nullptr; // created on demand
- foreach (const AndroidDeviceInfo &device, devices) {
- QString error;
- if (device.state == AndroidDeviceInfo::UnAuthorizedState) {
- error = AndroidDeviceDialog::tr("Unauthorized. Please check the confirmation dialog on your device %1.")
- .arg(device.serialNumber);
- }else if (device.state == AndroidDeviceInfo::OfflineState) {
- error = AndroidDeviceDialog::tr("Offline. Please check the state of your device %1.")
- .arg(device.serialNumber);
- } else if (!AndroidManager::matchedAbis(device.cpuAbi, m_abis)) {
- error = AndroidDeviceDialog::tr("ABI is incompatible, device supports ABIs: %1.")
- .arg(device.cpuAbi.join(QLatin1Char(' ')));
- } else if (device.sdk < m_apiLevel) {
- error = AndroidDeviceDialog::tr("API Level of device is: %1.")
- .arg(device.sdk);
- } else {
- new AndroidDeviceModelNode(compatibleDevices, device);
- continue;
- }
- if (!incompatibleDevices)
- incompatibleDevices = new AndroidDeviceModelNode(m_root, AndroidDeviceDialog::tr("Incompatible devices"));
- new AndroidDeviceModelNode(incompatibleDevices, device, error);
- }
- endResetModel();
-}
-
-QModelIndex AndroidDeviceModel::indexFor(AndroidDeviceInfo::AndroidDeviceType type, const QString &serial)
-{
- foreach (AndroidDeviceModelNode *topLevelNode, m_root->children()) {
- QList<AndroidDeviceModelNode *> deviceNodes = topLevelNode->children();
- for (int i = 0; i < deviceNodes.size(); ++i) {
- const AndroidDeviceInfo &info = deviceNodes.at(i)->deviceInfo();
- if (info.type != type)
- continue;
- if ((type == AndroidDeviceInfo::Hardware && serial == info.serialNumber)
- || (type == AndroidDeviceInfo::Emulator && serial == info.avdname))
- return createIndex(i, 0, deviceNodes.at(i));
- }
- }
- return QModelIndex();
-}
-
-/////////////////
-// AndroidDeviceDialog
-/////////////////
-
-static inline QString msgConnect()
-{
- return AndroidDeviceDialog::tr("<p>Connect an Android device via USB and activate developer mode on it. "
- "Some devices require the installation of a USB driver.</p>");
-
-}
-
-static inline QString msgAdbListDevices()
-{
- return AndroidDeviceDialog::tr("<p>The adb tool in the Android SDK lists all connected devices if run via &quot;adb devices&quot;.</p>");
-}
-
-AndroidDeviceDialog::AndroidDeviceDialog(int apiLevel, const QStringList &abis,
- const QString &serialNumber, QWidget *parent) :
- QDialog(parent),
- m_model(new AndroidDeviceModel(apiLevel, abis)),
- m_ui(new Ui::AndroidDeviceDialog),
- m_apiLevel(apiLevel),
- m_abis(abis),
- m_defaultDevice(serialNumber),
- m_avdManager(new AndroidAvdManager)
-{
- m_ui->setupUi(this);
- m_ui->deviceView->setModel(m_model);
- m_ui->deviceView->setItemDelegate(new AndroidDeviceModelDelegate(m_ui->deviceView));
- m_ui->deviceView->setHeaderHidden(true);
- m_ui->deviceView->setRootIsDecorated(false);
- m_ui->deviceView->setUniformRowHeights(true);
- m_ui->deviceView->setExpandsOnDoubleClick(false);
-
- m_ui->defaultDeviceCheckBox->setText(tr("Always use this device for this project"));
-
- m_ui->noDeviceFoundLabel->setText(QLatin1String("<p align=\"center\"><span style=\" font-size:16pt;\">")
- + tr("No Device Found") + QLatin1String("</span></p><br/>")
- + msgConnect() + QLatin1String("<br/>")
- + msgAdbListDevices());
- connect(m_ui->missingLabel, &QLabel::linkActivated,
- this, &AndroidDeviceDialog::showHelp);
-
- connect(m_ui->refreshDevicesButton, &QAbstractButton::clicked,
- this, &AndroidDeviceDialog::refreshDeviceList);
-
- connect(m_ui->createAVDButton, &QAbstractButton::clicked,
- this, &AndroidDeviceDialog::createAvd);
- connect(m_ui->deviceView, &QAbstractItemView::doubleClicked,
- this, &QDialog::accept);
-
- connect(&m_futureWatcherAddDevice, &QFutureWatcherBase::finished,
- this, &AndroidDeviceDialog::avdAdded);
- connect(&m_futureWatcherRefreshDevices, &QFutureWatcherBase::finished,
- this, &AndroidDeviceDialog::devicesRefreshed);
-
- connect(m_ui->deviceView->selectionModel(), &QItemSelectionModel::currentChanged,
- this, &AndroidDeviceDialog::enableOkayButton);
-
- m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
-
- m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicatorSize::Large, this);
- m_progressIndicator->attachToWidget(m_ui->deviceView);
-
- if (serialNumber.isEmpty()) {
- m_ui->lookingForDevice->setVisible(false);
- m_ui->lookingForDeviceCancel->setVisible(false);
- } else {
- m_ui->lookingForDevice->setVisible(true);
- m_ui->lookingForDevice->setText(tr("Looking for default device <b>%1</b>.").arg(serialNumber));
- m_ui->lookingForDeviceCancel->setVisible(true);
- }
-
- connect(m_ui->lookingForDeviceCancel, &QPushButton::clicked,
- this, &AndroidDeviceDialog::defaultDeviceClear);
-}
-
-AndroidDeviceDialog::~AndroidDeviceDialog()
-{
- m_futureWatcherAddDevice.waitForFinished();
- m_futureWatcherRefreshDevices.waitForFinished();
- delete m_ui;
-}
-
-AndroidDeviceInfo AndroidDeviceDialog::defaultDeviceInfo(const QString &serialNumber)
-{
- AndroidDeviceDialog::updateConnectedDevicesList();
-
- if (serialNumber.isEmpty())
- return {};
-
- return Utils::findOrDefault(m_connectedDevices, [serialNumber](const AndroidDeviceInfo &info) {
- return info.serialNumber == serialNumber || info.avdname == serialNumber;
- });
-}
-
-AndroidDeviceInfo AndroidDeviceDialog::showAndGetSelectedDevice()
-{
- auto dev = defaultDeviceInfo(m_defaultDevice);
- if (dev.isValid())
- return dev;
-
- refreshDeviceList();
-
- if (exec() == QDialog::Accepted)
- return m_model->device(m_ui->deviceView->currentIndex());
-
- return {};
-}
-
-bool AndroidDeviceDialog::saveDeviceSelection() const
-{
- return m_ui->defaultDeviceCheckBox->isChecked();
-}
-
-void AndroidDeviceDialog::updateConnectedDevicesList()
-{
- m_connectedDevices = AndroidConfig::connectedDevices(AndroidConfigurations::currentConfig()
- .adbToolPath());
-}
-
-void AndroidDeviceDialog::refreshDeviceList()
-{
- m_ui->refreshDevicesButton->setEnabled(false);
- m_progressIndicator->show();
- m_futureWatcherRefreshDevices.setFuture(m_avdManager->avdList());
-}
-
-void AndroidDeviceDialog::devicesRefreshed()
-{
- m_progressIndicator->hide();
- QString serialNumber;
- AndroidDeviceInfo::AndroidDeviceType deviceType = AndroidDeviceInfo::Hardware;
- QModelIndex currentIndex = m_ui->deviceView->currentIndex();
- if (currentIndex.isValid()) { // save currently selected index
- AndroidDeviceInfo info = m_model->device(currentIndex);
- deviceType = info.type;
- serialNumber = deviceType == AndroidDeviceInfo::Hardware ? info.serialNumber : info.avdname;
- }
-
- AndroidDeviceInfoList devices = m_futureWatcherRefreshDevices.result();
- QSet<QString> startedAvds = Utils::transform<QSet>(m_connectedDevices,
- &AndroidDeviceInfo::avdname);
-
- for (const AndroidDeviceInfo &dev : devices)
- if (!startedAvds.contains(dev.avdname))
- m_connectedDevices << dev;
-
- m_model->setDevices(m_connectedDevices);
-
- m_ui->deviceView->expand(m_model->index(0, 0));
- if (m_model->rowCount() > 1) // we have a incompatible device node
- m_ui->deviceView->expand(m_model->index(1, 0));
-
- // Smartly select a index
- QModelIndex newIndex;
- if (!m_defaultDevice.isEmpty()) {
- newIndex = m_model->indexFor(AndroidDeviceInfo::Hardware, m_defaultDevice);
- if (!newIndex.isValid())
- newIndex = m_model->indexFor(AndroidDeviceInfo::Emulator, m_defaultDevice);
- if (!newIndex.isValid()) // not found the default device
- defaultDeviceClear();
- }
-
- if (!newIndex.isValid() && !m_avdNameFromAdd.isEmpty()) {
- newIndex = m_model->indexFor(AndroidDeviceInfo::Emulator, m_avdNameFromAdd);
- m_avdNameFromAdd.clear();
- }
-
- if (!newIndex.isValid() && !serialNumber.isEmpty())
- newIndex = m_model->indexFor(deviceType, serialNumber);
-
- if (!newIndex.isValid() && !m_connectedDevices.isEmpty()) {
- AndroidDeviceInfo info = m_connectedDevices.first();
- const QString &name = info.type == AndroidDeviceInfo::Hardware ? info.serialNumber : info.avdname;
- newIndex = m_model->indexFor(info.type, name);
- }
-
- m_ui->deviceView->setCurrentIndex(newIndex);
-
- m_ui->stackedWidget->setCurrentIndex(m_connectedDevices.isEmpty() ? 1 : 0);
-
- m_ui->refreshDevicesButton->setEnabled(true);
- m_connectedDevices.clear();
-}
-
-void AndroidDeviceDialog::createAvd()
-{
- m_ui->createAVDButton->setEnabled(false);
- CreateAvdInfo info = AvdDialog::gatherCreateAVDInfo(this, AndroidConfigurations::sdkManager(),
- AndroidConfigurations::currentConfig(), m_apiLevel, m_abis);
-
- if (!info.isValid()) {
- m_ui->createAVDButton->setEnabled(true);
- return;
- }
-
- m_futureWatcherAddDevice.setFuture(m_avdManager->createAvd(info));
-}
-
-void AndroidDeviceDialog::avdAdded()
-{
- m_ui->createAVDButton->setEnabled(true);
- CreateAvdInfo info = m_futureWatcherAddDevice.result();
- if (!info.error.isEmpty()) {
- QMessageBox::critical(this, QApplication::translate("AndroidConfig", "Error Creating AVD"), info.error);
- return;
- }
-
- m_avdNameFromAdd = info.name;
- refreshDeviceList();
-}
-
-void AndroidDeviceDialog::enableOkayButton()
-{
- AndroidDeviceModelNode *node = static_cast<AndroidDeviceModelNode *>(m_ui->deviceView->currentIndex().internalPointer());
- bool enable = node && (!node->deviceInfo().serialNumber.isEmpty() || !node->deviceInfo().avdname.isEmpty());
- m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(enable);
-}
-
-void AndroidDeviceDialog::showHelp()
-{
- QPoint pos = m_ui->missingLabel->pos();
- pos = m_ui->missingLabel->parentWidget()->mapToGlobal(pos);
- QToolTip::showText(pos, msgConnect() + msgAdbListDevices(), this);
-}
-
-void AndroidDeviceDialog::defaultDeviceClear()
-{
- m_ui->lookingForDevice->setVisible(false);
- m_ui->lookingForDeviceCancel->setVisible(false);
- m_defaultDevice.clear();
-}
-
-#include "androiddevicedialog.moc"
diff --git a/src/plugins/android/androiddevicedialog.h b/src/plugins/android/androiddevicedialog.h
deleted file mode 100644
index 33bd2871e9..0000000000
--- a/src/plugins/android/androiddevicedialog.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and 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.
-**
-** 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.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "androidconfigurations.h"
-
-#include <QVector>
-#include <QDialog>
-#include <QFutureWatcher>
-#include <QTime>
-
-#include <memory>
-
-QT_BEGIN_NAMESPACE
-class QModelIndex;
-QT_END_NAMESPACE
-
-namespace Utils { class ProgressIndicator; }
-
-namespace Android {
-namespace Internal {
-
-class AndroidAvdManager;
-class AndroidDeviceModel;
-namespace Ui { class AndroidDeviceDialog; }
-
-class AndroidDeviceDialog : public QDialog
-{
- Q_OBJECT
-
-public:
- explicit AndroidDeviceDialog(int apiLevel, const QStringList &abis,
- const QString &serialNumber, QWidget *parent = nullptr);
- ~AndroidDeviceDialog() override;
-
- AndroidDeviceInfo showAndGetSelectedDevice();
- static AndroidDeviceInfo defaultDeviceInfo(const QString &serialNumber);
-
- bool saveDeviceSelection() const;
-
-private:
- void refreshDeviceList();
- void createAvd();
- void showHelp();
- void avdAdded();
- void devicesRefreshed();
- void enableOkayButton();
- void defaultDeviceClear();
- static void updateConnectedDevicesList();
-
- AndroidDeviceModel *m_model;
- Ui::AndroidDeviceDialog *m_ui;
- Utils::ProgressIndicator *m_progressIndicator;
- int m_apiLevel;
- QStringList m_abis;
- QString m_avdNameFromAdd;
- QString m_defaultDevice;
- static QVector<AndroidDeviceInfo> m_connectedDevices;
- std::unique_ptr<AndroidAvdManager> m_avdManager;
- QFutureWatcher<CreateAvdInfo> m_futureWatcherAddDevice;
- QFutureWatcher<AndroidDeviceInfoList> m_futureWatcherRefreshDevices;
-};
-
-}
-}
diff --git a/src/plugins/android/androiddevicedialog.ui b/src/plugins/android/androiddevicedialog.ui
deleted file mode 100644
index aac84c80ec..0000000000
--- a/src/plugins/android/androiddevicedialog.ui
+++ /dev/null
@@ -1,215 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>Android::Internal::AndroidDeviceDialog</class>
- <widget class="QDialog" name="Android::Internal::AndroidDeviceDialog">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>788</width>
- <height>466</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>Select Android Device</string>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="6" column="2">
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="2" column="0" colspan="2">
- <widget class="QCheckBox" name="defaultDeviceCheckBox">
- <property name="toolTip">
- <string>This can be later reset in deployment settings in the Projects mode.</string>
- </property>
- <property name="text">
- <string>Always use this device for architecture %1 for this project</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0" colspan="4">
- <widget class="QStackedWidget" name="stackedWidget">
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="devicesPage">
- <layout class="QGridLayout" name="gridLayout_3">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item row="1" column="0" colspan="2">
- <widget class="QTreeView" name="deviceView">
- <property name="minimumSize">
- <size>
- <width>600</width>
- <height>300</height>
- </size>
- </property>
- </widget>
- </item>
- <item row="2" column="0" colspan="2">
- <widget class="QLabel" name="missingLabel">
- <property name="text">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;aaa&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0057ae;&quot;&gt;My device is missing&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="textFormat">
- <enum>Qt::RichText</enum>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="lookingForDevice">
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QPushButton" name="lookingForDeviceCancel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Cancel</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="noDevicesPage">
- <layout class="QGridLayout" name="gridLayout_2">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="noDeviceFoundLabel">
- <property name="text">
- <string notr="true">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="textFormat">
- <enum>Qt::RichText</enum>
- </property>
- <property name="alignment">
- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- <item row="8" column="0" colspan="4">
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- <item row="6" column="1">
- <widget class="QPushButton" name="createAVDButton">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Create Android Virtual Device</string>
- </property>
- </widget>
- </item>
- <item row="6" column="0">
- <widget class="QPushButton" name="refreshDevicesButton">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Refresh Device List</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>lookingForDeviceCancel</tabstop>
- <tabstop>deviceView</tabstop>
- <tabstop>defaultDeviceCheckBox</tabstop>
- <tabstop>refreshDevicesButton</tabstop>
- <tabstop>createAVDButton</tabstop>
- </tabstops>
- <resources/>
- <connections>
- <connection>
- <sender>buttonBox</sender>
- <signal>accepted()</signal>
- <receiver>Android::Internal::AndroidDeviceDialog</receiver>
- <slot>accept()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>248</x>
- <y>254</y>
- </hint>
- <hint type="destinationlabel">
- <x>157</x>
- <y>274</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>buttonBox</sender>
- <signal>rejected()</signal>
- <receiver>Android::Internal::AndroidDeviceDialog</receiver>
- <slot>reject()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>316</x>
- <y>260</y>
- </hint>
- <hint type="destinationlabel">
- <x>286</x>
- <y>274</y>
- </hint>
- </hints>
- </connection>
- </connections>
-</ui>
diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp
index d5177de681..7d181c405b 100644
--- a/src/plugins/android/androidmanager.cpp
+++ b/src/plugins/android/androidmanager.cpp
@@ -25,16 +25,17 @@
#include "androidmanager.h"
+#include "androidavdmanager.h"
#include "androidbuildapkstep.h"
-#include "androidconstants.h"
#include "androidconfigurations.h"
-#include "androidrunconfiguration.h"
-#include "androidglobal.h"
-#include "androidtoolchain.h"
+#include "androidconstants.h"
#include "androiddeployqtstep.h"
+#include "androiddevice.h"
+#include "androidglobal.h"
#include "androidqtversion.h"
-#include "androidavdmanager.h"
+#include "androidrunconfiguration.h"
#include "androidsdkmanager.h"
+#include "androidtoolchain.h"
#include <coreplugin/documentmanager.h>
#include <coreplugin/messagemanager.h>
@@ -552,7 +553,8 @@ void AndroidManager::installQASIPackage(Target *target, const FilePath &packageP
if (appAbis.isEmpty())
return;
const int deviceAPILevel = AndroidManager::minimumSDK(target);
- AndroidDeviceInfo info = AndroidConfigurations::showDeviceDialog(target->project(), deviceAPILevel, appAbis);
+ const IDevice::ConstPtr device = DeviceKitAspect::device(target->kit());
+ AndroidDeviceInfo info = AndroidDevice::androidDeviceInfoFromIDevice(device.data());
if (!info.isValid()) // aborted
return;
diff --git a/src/plugins/android/androidpotentialkit.cpp b/src/plugins/android/androidpotentialkit.cpp
index efb266a27a..b2d5bbe7cb 100644
--- a/src/plugins/android/androidpotentialkit.cpp
+++ b/src/plugins/android/androidpotentialkit.cpp
@@ -69,9 +69,7 @@ bool AndroidPotentialKit::isEnabled() const
QList<ProjectExplorer::Kit *> kits = ProjectExplorer::KitManager::kits();
foreach (ProjectExplorer::Kit *kit, kits) {
Utils::Id deviceId = ProjectExplorer::DeviceKitAspect::deviceId(kit);
- if (kit->isAutoDetected()
- && deviceId == Utils::Id(Constants::ANDROID_DEVICE_ID)
- && !kit->isSdkProvided()) {
+ if (kit->isAutoDetected() && !kit->isSdkProvided()) {
return false;
}
}
@@ -121,9 +119,7 @@ void AndroidPotentialKitWidget::recheck()
QList<ProjectExplorer::Kit *> kits = ProjectExplorer::KitManager::kits();
foreach (ProjectExplorer::Kit *kit, kits) {
Utils::Id deviceId = ProjectExplorer::DeviceKitAspect::deviceId(kit);
- if (kit->isAutoDetected()
- && deviceId == Utils::Id(Constants::ANDROID_DEVICE_ID)
- && !kit->isSdkProvided()) {
+ if (kit->isAutoDetected() && !kit->isSdkProvided()) {
setVisible(false);
return;
}
diff --git a/src/plugins/android/androidrunner.cpp b/src/plugins/android/androidrunner.cpp
index 1682d882b4..c0266e1d71 100644
--- a/src/plugins/android/androidrunner.cpp
+++ b/src/plugins/android/androidrunner.cpp
@@ -26,12 +26,13 @@
#include "androidrunner.h"
+#include "androidavdmanager.h"
+#include "androidconfigurations.h"
#include "androidconstants.h"
#include "androiddeployqtstep.h"
-#include "androidconfigurations.h"
-#include "androidrunconfiguration.h"
+#include "androiddevice.h"
#include "androidmanager.h"
-#include "androidavdmanager.h"
+#include "androidrunconfiguration.h"
#include "androidrunnerworker.h"
#include <coreplugin/messagemanager.h>
@@ -39,6 +40,7 @@
#include <projectexplorer/projectexplorersettings.h>
#include <projectexplorer/runconfigurationaspects.h>
#include <projectexplorer/target.h>
+#include <qtsupport/qtkitinformation.h>
#include <utils/url.h>
#include <QHostAddress>
@@ -185,9 +187,9 @@ void AndroidRunner::launchAVD()
int deviceAPILevel = AndroidManager::minimumSDK(m_target);
QStringList androidAbis = AndroidManager::applicationAbis(m_target);
- // Get AVD info.
- AndroidDeviceInfo info = AndroidConfigurations::showDeviceDialog(
- m_target->project(), deviceAPILevel, androidAbis);
+ // Get AVD info
+ const IDevice::ConstPtr device = DeviceKitAspect::device(m_target->kit());
+ AndroidDeviceInfo info = AndroidDevice::androidDeviceInfoFromIDevice(device.data());
AndroidManager::setDeviceSerialNumber(m_target, info.serialNumber);
emit androidDeviceInfoChanged(info);
if (info.isValid()) {
diff --git a/src/plugins/projectexplorer/images/MaemoDevice.png b/src/plugins/projectexplorer/images/MaemoDevice.png
deleted file mode 100644
index 51886524cc..0000000000
--- a/src/plugins/projectexplorer/images/MaemoDevice.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/projectexplorer/images/Simulator.png b/src/plugins/projectexplorer/images/Simulator.png
deleted file mode 100644
index 447054bac8..0000000000
--- a/src/plugins/projectexplorer/images/Simulator.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/projectexplorer/projectexplorer.qrc b/src/plugins/projectexplorer/projectexplorer.qrc
index b09c7e26da..2c48d30a85 100644
--- a/src/plugins/projectexplorer/projectexplorer.qrc
+++ b/src/plugins/projectexplorer/projectexplorer.qrc
@@ -29,8 +29,6 @@
<file>images/RunSettings.png</file>
<file>images/EditorSettings.png</file>
<file>images/ProjectDependencies.png</file>
- <file>images/MaemoDevice.png</file>
- <file>images/Simulator.png</file>
<file>images/devicestatusindicator.png</file>
<file>images/devicestatusindicator@2x.png</file>
<file>images/build.png</file>
diff --git a/src/tools/iconlister/iconlister.cpp b/src/tools/iconlister/iconlister.cpp
index 17ebbc0306..a0283bacb2 100644
--- a/src/tools/iconlister/iconlister.cpp
+++ b/src/tools/iconlister/iconlister.cpp
@@ -344,10 +344,6 @@ void IconLister::addProjectExplorerIcons()
""},
{QIcon(":/projectexplorer/images/ProjectDependencies.png"), "ProjectDependencies.png", prefix,
""},
- {QIcon(":/projectexplorer/images/MaemoDevice.png"), "MaemoDevice.png", prefix,
- ""},
- {QIcon(":/projectexplorer/images/Simulator.png"), "Simulator.png", prefix,
- ""},
{QIcon(":/projectexplorer/images/targetpanel_bottom.png"), "targetpanel_bottom.png", prefix,
""},
{QIcon(":/projectexplorer/images/unconfigured.png"), "unconfigured.png", prefix,