Commit a128d383 authored by Sergey Shambir's avatar Sergey Shambir

Android: select device with "adb -d" if it have invalid serial no

Works only if no correctly detected devices attached to adb.

Sometimes serial number becomes '????-????-????' on linux because udev
rules are not configured, handling them without configuring will be
useful.

Also i have 2 phones that have no serial number at all on stock rom.

Serial number disappears on some smartphones with CyanogenMod
http://forum.cyanogenmod.org/topic/64522-i-have-no-serial-number/

Change-Id: I1a992eb2537342934c60d79c9180edd955aa7862
Reviewed-by: default avatarBogDan Vatra <bogdan@kde.org>
parent ebcb4209
...@@ -350,8 +350,23 @@ QVector<AndroidDeviceInfo> AndroidConfigurations::connectedDevices(int apiLevel) ...@@ -350,8 +350,23 @@ QVector<AndroidDeviceInfo> AndroidConfigurations::connectedDevices(int apiLevel)
QList<QByteArray> adbDevs = adbProc.readAll().trimmed().split('\n'); QList<QByteArray> adbDevs = adbProc.readAll().trimmed().split('\n');
adbDevs.removeFirst(); adbDevs.removeFirst();
AndroidDeviceInfo dev; AndroidDeviceInfo dev;
// workaround for '????????????' serial numbers:
// can use "adb -d" when only one usb device attached
int usbDevicesNum = 0;
QStringList serialNumbers;
foreach (const QByteArray &device, adbDevs) { foreach (const QByteArray &device, adbDevs) {
dev.serialNumber = QString::fromLatin1(device.left(device.indexOf('\t')).trimmed()); const QString serialNo = QString::fromLatin1(device.left(device.indexOf('\t')).trimmed());;
if (!serialNo.startsWith(QLatin1String("emulator")))
++usbDevicesNum;
serialNumbers << serialNo;
}
foreach (const QString &serialNo, serialNumbers) {
if (serialNo.contains(QLatin1String("????")) && usbDevicesNum > 1)
continue;
dev.serialNumber = serialNo;
dev.sdk = getSDKVersion(dev.serialNumber); dev.sdk = getSDKVersion(dev.serialNumber);
if (apiLevel != -1 && dev.sdk != apiLevel) if (apiLevel != -1 && dev.sdk != apiLevel)
continue; continue;
...@@ -522,12 +537,13 @@ QString AndroidConfigurations::startAVD(int *apiLevel, const QString &name) cons ...@@ -522,12 +537,13 @@ QString AndroidConfigurations::startAVD(int *apiLevel, const QString &name) cons
int AndroidConfigurations::getSDKVersion(const QString &device) const int AndroidConfigurations::getSDKVersion(const QString &device) const
{ {
// workaround for '????????????' serial numbers
QStringList arguments = AndroidDeviceInfo::adbSelector(device);
arguments << QLatin1String("shell") << QLatin1String("getprop")
<< QLatin1String("ro.build.version.sdk");
QProcess adbProc; QProcess adbProc;
adbProc.start(adbToolPath().toString(), adbProc.start(adbToolPath().toString(), arguments);
QStringList() << QLatin1String("-s") << device
<< QLatin1String("shell") << QLatin1String("getprop")
<< QLatin1String("ro.build.version.sdk"));
if (!adbProc.waitForFinished(-1)) { if (!adbProc.waitForFinished(-1)) {
adbProc.kill(); adbProc.kill();
return -1; return -1;
...@@ -644,6 +660,17 @@ void AndroidConfigurations::updateAutomaticKitList() ...@@ -644,6 +660,17 @@ void AndroidConfigurations::updateAutomaticKitList()
KitManager::instance()->registerKit(kit); KitManager::instance()->registerKit(kit);
} }
/**
* Workaround for '????????????' serial numbers
* @return ("-d") for buggy devices, ("-s", <serial no>) for normal
*/
QStringList AndroidDeviceInfo::adbSelector(const QString &serialNumber)
{
if (serialNumber.startsWith(QLatin1String("????")))
return QStringList() << QLatin1String("-d");
return QStringList() << QLatin1String("-s") << serialNumber;
}
AndroidConfigurations &AndroidConfigurations::instance(QObject *parent) AndroidConfigurations &AndroidConfigurations::instance(QObject *parent)
{ {
if (m_instance == 0) if (m_instance == 0)
......
...@@ -78,6 +78,8 @@ struct AndroidDeviceInfo ...@@ -78,6 +78,8 @@ struct AndroidDeviceInfo
QString serialNumber; QString serialNumber;
QString cpuABI; QString cpuABI;
int sdk; int sdk;
static QStringList adbSelector(const QString &serialNumber);
}; };
class AndroidConfigurations : public QObject class AndroidConfigurations : public QObject
......
...@@ -172,9 +172,8 @@ void AndroidDeployStep::cleanLibsOnDevice() ...@@ -172,9 +172,8 @@ void AndroidDeployStep::cleanLibsOnDevice()
return; return;
} }
QProcess *process = new QProcess(this); QProcess *process = new QProcess(this);
QStringList arguments; QStringList arguments = AndroidDeviceInfo::adbSelector(deviceSerialNumber);
arguments << QLatin1String("-s") << deviceSerialNumber arguments << QLatin1String("shell") << QLatin1String("rm") << QLatin1String("-r") << QLatin1String("/data/local/tmp/qt");
<< QLatin1String("shell") << QLatin1String("rm") << QLatin1String("-r") << QLatin1String("/data/local/tmp/qt");
connect(process, SIGNAL(finished(int)), this, SLOT(cleanLibsFinished())); connect(process, SIGNAL(finished(int)), this, SLOT(cleanLibsFinished()));
const QString adb = AndroidConfigurations::instance().adbToolPath().toString(); const QString adb = AndroidConfigurations::instance().adbToolPath().toString();
Core::MessageManager::instance()->printToOutputPanePopup(adb + QLatin1String(" ") Core::MessageManager::instance()->printToOutputPanePopup(adb + QLatin1String(" ")
...@@ -275,9 +274,8 @@ unsigned int AndroidDeployStep::remoteModificationTime(const QString &fullDestin ...@@ -275,9 +274,8 @@ unsigned int AndroidDeployStep::remoteModificationTime(const QString &fullDestin
QHash<QString, unsigned int>::const_iterator it = cache->find(fullDestination); QHash<QString, unsigned int>::const_iterator it = cache->find(fullDestination);
if (it != cache->constEnd()) if (it != cache->constEnd())
return *it; return *it;
QStringList arguments; QStringList arguments = AndroidDeviceInfo::adbSelector(m_deviceSerialNumber);
arguments << QLatin1String("-s") << m_deviceSerialNumber arguments << QLatin1String("ls") << destination;
<< QLatin1String("ls") << destination;
process.start(AndroidConfigurations::instance().adbToolPath().toString(), arguments); process.start(AndroidConfigurations::instance().adbToolPath().toString(), arguments);
process.waitForFinished(-1); process.waitForFinished(-1);
if (process.error() != QProcess::UnknownError if (process.error() != QProcess::UnknownError
...@@ -378,7 +376,7 @@ void AndroidDeployStep::deployFiles(QProcess *process, const QList<DeployItem> & ...@@ -378,7 +376,7 @@ void AndroidDeployStep::deployFiles(QProcess *process, const QList<DeployItem> &
{ {
foreach (const DeployItem &item, deployList) { foreach (const DeployItem &item, deployList) {
runCommand(process, AndroidConfigurations::instance().adbToolPath().toString(), runCommand(process, AndroidConfigurations::instance().adbToolPath().toString(),
QStringList() << QLatin1String("-s") << m_deviceSerialNumber AndroidDeviceInfo::adbSelector(m_deviceSerialNumber)
<< QLatin1String("push") << item.localFileName << QLatin1String("push") << item.localFileName
<< item.remoteFileName); << item.remoteFileName);
} }
...@@ -432,7 +430,7 @@ bool AndroidDeployStep::deployPackage() ...@@ -432,7 +430,7 @@ bool AndroidDeployStep::deployPackage()
if (m_runDeployAction == InstallQASI) { if (m_runDeployAction == InstallQASI) {
if (!runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(), if (!runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(),
QStringList() << QLatin1String("-s") << m_deviceSerialNumber AndroidDeviceInfo::adbSelector(m_deviceSerialNumber)
<< QLatin1String("install") << QLatin1String("-r ") << m_runQASIPackagePath)) { << QLatin1String("install") << QLatin1String("-r ") << m_runQASIPackagePath)) {
raiseError(tr("Qt Android smart installer installation failed")); raiseError(tr("Qt Android smart installer installation failed"));
disconnect(deployProc, 0, this, 0); disconnect(deployProc, 0, this, 0);
...@@ -445,7 +443,7 @@ bool AndroidDeployStep::deployPackage() ...@@ -445,7 +443,7 @@ bool AndroidDeployStep::deployPackage()
writeOutput(tr("Installing package onto %1.").arg(m_deviceSerialNumber)); writeOutput(tr("Installing package onto %1.").arg(m_deviceSerialNumber));
runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(), runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(),
QStringList() << QLatin1String("-s") << m_deviceSerialNumber << QLatin1String("uninstall") << m_packageName); AndroidDeviceInfo::adbSelector(m_deviceSerialNumber) << QLatin1String("uninstall") << m_packageName);
QString package = m_apkPathDebug; QString package = m_apkPathDebug;
if (!(m_qtVersionQMakeBuildConfig & QtSupport::BaseQtVersion::DebugBuild) if (!(m_qtVersionQMakeBuildConfig & QtSupport::BaseQtVersion::DebugBuild)
...@@ -453,7 +451,7 @@ bool AndroidDeployStep::deployPackage() ...@@ -453,7 +451,7 @@ bool AndroidDeployStep::deployPackage()
package = m_apkPathRelease; package = m_apkPathRelease;
if (!runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(), if (!runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(),
QStringList() << QLatin1String("-s") << m_deviceSerialNumber << QLatin1String("install") << package)) { AndroidDeviceInfo::adbSelector(m_deviceSerialNumber) << QLatin1String("install") << package)) {
raiseError(tr("Package installation failed.")); raiseError(tr("Package installation failed."));
disconnect(deployProc, 0, this, 0); disconnect(deployProc, 0, this, 0);
deployProc->deleteLater(); deployProc->deleteLater();
...@@ -462,11 +460,11 @@ bool AndroidDeployStep::deployPackage() ...@@ -462,11 +460,11 @@ bool AndroidDeployStep::deployPackage()
writeOutput(tr("Pulling files necessary for debugging.")); writeOutput(tr("Pulling files necessary for debugging."));
runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(), runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(),
QStringList() << QLatin1String("-s") << m_deviceSerialNumber AndroidDeviceInfo::adbSelector(m_deviceSerialNumber)
<< QLatin1String("pull") << QLatin1String("/system/bin/app_process") << QLatin1String("pull") << QLatin1String("/system/bin/app_process")
<< QString::fromLatin1("%1/app_process").arg(m_buildDirectory)); << QString::fromLatin1("%1/app_process").arg(m_buildDirectory));
runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(), runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(),
QStringList() << QLatin1String("-s") << m_deviceSerialNumber << QLatin1String("pull") AndroidDeviceInfo::adbSelector(m_deviceSerialNumber) << QLatin1String("pull")
<< QLatin1String("/system/lib/libc.so") << QLatin1String("/system/lib/libc.so")
<< QString::fromLatin1("%1/libc.so").arg(m_buildDirectory)); << QString::fromLatin1("%1/libc.so").arg(m_buildDirectory));
disconnect(deployProc, 0, this, 0); disconnect(deployProc, 0, this, 0);
......
...@@ -80,7 +80,7 @@ void AndroidRunner::checkPID() ...@@ -80,7 +80,7 @@ void AndroidRunner::checkPID()
// Detect busybox, as we need to pass -w to it to get wide output. // Detect busybox, as we need to pass -w to it to get wide output.
psProc.start(AndroidConfigurations::instance().adbToolPath().toString(), psProc.start(AndroidConfigurations::instance().adbToolPath().toString(),
QStringList() << QLatin1String("-s") << m_deviceSerialNumber AndroidDeviceInfo::adbSelector(m_deviceSerialNumber)
<< QLatin1String("shell") << QLatin1String("readlink") << QLatin1String("$(which ps)")); << QLatin1String("shell") << QLatin1String("readlink") << QLatin1String("$(which ps)"));
if (!psProc.waitForFinished(-1)) { if (!psProc.waitForFinished(-1)) {
psProc.kill(); psProc.kill();
...@@ -93,7 +93,7 @@ void AndroidRunner::checkPID() ...@@ -93,7 +93,7 @@ void AndroidRunner::checkPID()
} }
psProc.start(AndroidConfigurations::instance().adbToolPath().toString(), psProc.start(AndroidConfigurations::instance().adbToolPath().toString(),
QStringList() << QLatin1String("-s") << m_deviceSerialNumber AndroidDeviceInfo::adbSelector(m_deviceSerialNumber)
<< QLatin1String("shell") << psCmd); << QLatin1String("shell") << psCmd);
if (!psProc.waitForFinished(-1)) { if (!psProc.waitForFinished(-1)) {
psProc.kill(); psProc.kill();
...@@ -161,9 +161,8 @@ void AndroidRunner::asyncStart() ...@@ -161,9 +161,8 @@ void AndroidRunner::asyncStart()
QString extraParams; QString extraParams;
QProcess adbStarProc; QProcess adbStarProc;
if (m_useCppDebugger) { if (m_useCppDebugger) {
QStringList arguments; QStringList arguments = AndroidDeviceInfo::adbSelector(m_deviceSerialNumber);
arguments << QLatin1String("-s") << m_deviceSerialNumber arguments << QLatin1String("forward") << QString::fromLatin1("tcp%1").arg(m_remoteGdbChannel)
<< QLatin1String("forward") << QString::fromLatin1("tcp%1").arg(m_remoteGdbChannel)
<< QString::fromLatin1("localfilesystem:/data/data/%1/debug-socket").arg(m_packageName); << QString::fromLatin1("localfilesystem:/data/data/%1/debug-socket").arg(m_packageName);
adbStarProc.start(AndroidConfigurations::instance().adbToolPath().toString(), arguments); adbStarProc.start(AndroidConfigurations::instance().adbToolPath().toString(), arguments);
if (!adbStarProc.waitForStarted()) { if (!adbStarProc.waitForStarted()) {
...@@ -177,10 +176,9 @@ void AndroidRunner::asyncStart() ...@@ -177,10 +176,9 @@ void AndroidRunner::asyncStart()
extraParams = QLatin1String("-e native_debug true -e gdbserver_socket +debug-socket"); extraParams = QLatin1String("-e native_debug true -e gdbserver_socket +debug-socket");
} }
if (m_useQmlDebugger) { if (m_useQmlDebugger) {
QStringList arguments; QStringList arguments = AndroidDeviceInfo::adbSelector(m_deviceSerialNumber);
QString port = QString::fromLatin1("tcp:%1").arg(m_qmlPort); QString port = QString::fromLatin1("tcp:%1").arg(m_qmlPort);
arguments << QLatin1String("-s") << m_deviceSerialNumber arguments << QLatin1String("forward") << port << port; // currently forward to same port on device and host
<< QLatin1String("forward") << port << port; // currently forward to same port on device and host
adbStarProc.start(AndroidConfigurations::instance().adbToolPath().toString(), arguments); adbStarProc.start(AndroidConfigurations::instance().adbToolPath().toString(), arguments);
if (!adbStarProc.waitForStarted()) { if (!adbStarProc.waitForStarted()) {
emit remoteProcessFinished(tr("Failed to forward QML debugging ports. Reason: %1.").arg(adbStarProc.errorString())); emit remoteProcessFinished(tr("Failed to forward QML debugging ports. Reason: %1.").arg(adbStarProc.errorString()));
...@@ -204,9 +202,8 @@ void AndroidRunner::asyncStart() ...@@ -204,9 +202,8 @@ void AndroidRunner::asyncStart()
} }
extraParams = extraParams.trimmed(); extraParams = extraParams.trimmed();
QStringList arguments; QStringList arguments = AndroidDeviceInfo::adbSelector(m_deviceSerialNumber);
arguments << QLatin1String("-s") << m_deviceSerialNumber arguments << QLatin1String("shell") << QLatin1String("am")
<< QLatin1String("shell") << QLatin1String("am")
<< QLatin1String("start") << QLatin1String("-n") << m_intentName; << QLatin1String("start") << QLatin1String("-n") << m_intentName;
if (extraParams.length()) if (extraParams.length())
...@@ -246,7 +243,7 @@ void AndroidRunner::startLogcat() ...@@ -246,7 +243,7 @@ void AndroidRunner::startLogcat()
{ {
m_checkPIDTimer.start(1000); // check if the application is alive every 1 seconds m_checkPIDTimer.start(1000); // check if the application is alive every 1 seconds
m_adbLogcatProcess.start(AndroidConfigurations::instance().adbToolPath().toString(), m_adbLogcatProcess.start(AndroidConfigurations::instance().adbToolPath().toString(),
QStringList() << QLatin1String("-s") << m_deviceSerialNumber AndroidDeviceInfo::adbSelector(m_deviceSerialNumber)
<< QLatin1String("logcat")); << QLatin1String("logcat"));
emit remoteProcessStarted(5039); emit remoteProcessStarted(5039);
} }
...@@ -294,9 +291,8 @@ void AndroidRunner::logcatReadStandardOutput() ...@@ -294,9 +291,8 @@ void AndroidRunner::logcatReadStandardOutput()
void AndroidRunner::adbKill(qint64 pid, const QString &device, int timeout, const QString &runAsPackageName) void AndroidRunner::adbKill(qint64 pid, const QString &device, int timeout, const QString &runAsPackageName)
{ {
QProcess process; QProcess process;
QStringList arguments; QStringList arguments = AndroidDeviceInfo::adbSelector(device);
arguments << QLatin1String("-s") << device;
arguments << QLatin1String("shell"); arguments << QLatin1String("shell");
if (runAsPackageName.size()) if (runAsPackageName.size())
arguments << QLatin1String("run-as") << runAsPackageName; arguments << QLatin1String("run-as") << runAsPackageName;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment