Starting AVD in run step. Before this change AVD was started only in deploy step.

Task-number: QTCREATORBUG-10237
Change-Id: Ic99cc84013e53ddc60ed05c7983e141ecfc75169
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
Reviewed-by: BogDan Vatra <bogdan@kdab.com>
This commit is contained in:
Vikas Pachdha
2016-06-08 16:57:32 +02:00
committed by Vikas Pachdha
parent 602f8e72be
commit 148d7636f1
2 changed files with 82 additions and 6 deletions

View File

@@ -33,6 +33,9 @@
#include "androidmanager.h" #include "androidmanager.h"
#include <debugger/debuggerrunconfigurationaspect.h> #include <debugger/debuggerrunconfigurationaspect.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectexplorersettings.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <qtsupport/qtkitinformation.h> #include <qtsupport/qtkitinformation.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -46,6 +49,8 @@
#include <QTcpServer> #include <QTcpServer>
#include <QTcpSocket> #include <QTcpSocket>
using namespace ProjectExplorer;
/* /*
This uses explicit handshakes between the application and the This uses explicit handshakes between the application and the
gdbserver start and the host side by using the gdbserver socket. gdbserver start and the host side by using the gdbserver socket.
@@ -122,8 +127,10 @@ static int socketHandShakePort = MIN_SOCKET_HANDSHAKE_PORT;
AndroidRunner::AndroidRunner(QObject *parent, AndroidRunner::AndroidRunner(QObject *parent,
AndroidRunConfiguration *runConfig, AndroidRunConfiguration *runConfig,
Core::Id runMode) Core::Id runMode)
: QThread(parent), m_handShakeMethod(SocketHandShake), m_socket(0), : QThread(parent)
m_customPort(false) , m_runConfig(runConfig)
, m_handShakeMethod(SocketHandShake), m_socket(0)
, m_customPort(false)
{ {
m_tries = 0; m_tries = 0;
Debugger::DebuggerRunConfigurationAspect *aspect Debugger::DebuggerRunConfigurationAspect *aspect
@@ -268,6 +275,13 @@ QByteArray AndroidRunner::runPs()
} }
} }
void AndroidRunner::launchAVDProcesses()
{
// Its assumed that the device or avd serial returned by selector() is online.
m_adbLogcatProcess.start(m_adb, selector() << _("logcat"));
m_psProc.start(m_adb, selector() << _("shell"));
}
void AndroidRunner::checkPID() void AndroidRunner::checkPID()
{ {
QByteArray psOut = runPs(); QByteArray psOut = runPs();
@@ -327,14 +341,40 @@ void AndroidRunner::forceStop()
void AndroidRunner::start() void AndroidRunner::start()
{ {
m_adbLogcatProcess.start(m_adb, selector() << _("logcat")); if (!ProjectExplorerPlugin::projectExplorerSettings().deployBeforeRun) {
m_psProc.start(m_adb, selector() << _("shell")); // User choose to run the app without deployment. Start the AVD if not running.
launchAVD();
}
Utils::runAsync(&AndroidRunner::asyncStart, this); Utils::runAsync(&AndroidRunner::asyncStart, this);
} }
void AndroidRunner::asyncStart() void AndroidRunner::asyncStart()
{ {
if (!ProjectExplorerPlugin::projectExplorerSettings().deployBeforeRun && !m_launchedAVDName.isEmpty()) {
// AVD was started. Wait for the avd to boot before launching the app.
m_avdFutureInterface = QFutureInterface<bool>();
m_avdFutureInterface.reportStarted();
QString serialNumber = AndroidConfigurations::currentConfig()
.waitForAvd(m_launchedAVDName, m_avdFutureInterface);
if (m_avdFutureInterface.isCanceled()) {
// User stopped the run step before AVD start. Bail out.
m_avdFutureInterface.reportFinished();
return;
} else {
QMetaObject::invokeMethod(this, "launchAVDProcesses", Qt::BlockingQueuedConnection);
AndroidManager::setDeviceSerialNumber(m_runConfig->target(), serialNumber);
m_avdFutureInterface.reportFinished();
}
} else {
// AVD/device available.
QMetaObject::invokeMethod(this, "launchAVDProcesses", Qt::BlockingQueuedConnection);
}
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
forceStop(); forceStop();
QString errorMessage; QString errorMessage;
@@ -493,6 +533,30 @@ bool AndroidRunner::adbShellAmNeedsQuotes()
return !oldSdk; return !oldSdk;
} }
void AndroidRunner::launchAVD()
{
if (!m_runConfig->target() && !m_runConfig->target()->project())
return;
int deviceAPILevel = AndroidManager::minimumSDK(m_runConfig->target());
QString targetArch = AndroidManager::targetArch(m_runConfig->target());
// Get AVD info.
AndroidDeviceInfo info = AndroidConfigurations::showDeviceDialog(m_runConfig->target()->project(), deviceAPILevel,
targetArch, AndroidConfigurations::None);
AndroidManager::setDeviceSerialNumber(m_runConfig->target(), info.serialNumber);
m_androidRunnable.deviceSerialNumber = info.serialNumber;
m_selector = AndroidDeviceInfo::adbSelector(info.serialNumber);
if (info.isValid()) {
if (AndroidConfigurations::currentConfig().findAvd(info.avdname).isEmpty()) {
bool launched = AndroidConfigurations::currentConfig().startAVDAsync(info.avdname);
m_launchedAVDName = launched ? info.avdname:"";
} else {
m_launchedAVDName.clear();
}
}
}
bool AndroidRunner::runAdb(const QStringList &args, QString *errorMessage, int timeoutS) bool AndroidRunner::runAdb(const QStringList &args, QString *errorMessage, int timeoutS)
{ {
Utils::SynchronousProcess adb; Utils::SynchronousProcess adb;
@@ -525,6 +589,13 @@ void AndroidRunner::handleRemoteDebuggerRunning()
void AndroidRunner::stop() void AndroidRunner::stop()
{ {
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
if (m_avdFutureInterface.isRunning()) {
m_avdFutureInterface.cancel();
m_avdFutureInterface.waitForFinished();
emit remoteProcessFinished(QLatin1String("\n\n") + tr("\"%1\" terminated.").arg(m_androidRunnable.packageName));
}
m_checkPIDTimer.stop(); m_checkPIDTimer.stop();
m_tries = 0; m_tries = 0;
if (m_processPID != -1) { if (m_processPID != -1) {

View File

@@ -31,6 +31,7 @@
#include <projectexplorer/runconfiguration.h> #include <projectexplorer/runconfiguration.h>
#include <qmldebug/qmldebugcommandlinearguments.h> #include <qmldebug/qmldebugcommandlinearguments.h>
#include <QFutureInterface>
#include <QObject> #include <QObject>
#include <QTimer> #include <QTimer>
#include <QTcpSocket> #include <QTcpSocket>
@@ -80,15 +81,19 @@ private:
void logcatReadStandardOutput(); void logcatReadStandardOutput();
void asyncStart(); void asyncStart();
Q_INVOKABLE QByteArray runPs(); Q_INVOKABLE QByteArray runPs();
Q_INVOKABLE void launchAVDProcesses();
void adbKill(qint64 pid); void adbKill(qint64 pid);
QStringList selector() const { return m_selector; } QStringList selector() const { return m_selector; }
void forceStop(); void forceStop();
void findPs(); void findPs();
void logcatProcess(const QByteArray &text, QByteArray &buffer, bool onlyError); void logcatProcess(const QByteArray &text, QByteArray &buffer, bool onlyError);
bool adbShellAmNeedsQuotes(); bool adbShellAmNeedsQuotes();
void launchAVD();
bool runAdb(const QStringList &args, QString *errorMessage = nullptr, int timeoutS = 10); bool runAdb(const QStringList &args, QString *errorMessage = nullptr, int timeoutS = 10);
private:
AndroidRunConfiguration *m_runConfig;
QString m_launchedAVDName;
QFutureInterface<bool> m_avdFutureInterface;
QProcess m_adbLogcatProcess; QProcess m_adbLogcatProcess;
QProcess m_psProc; QProcess m_psProc;
QTimer m_checkPIDTimer; QTimer m_checkPIDTimer;