iOS: Do not post message on fallback transfer as error

Amends 84cc7208de

Since that change, "error" messages from iostool are posted as errors in
the Issues view. The problem with that is that iostool did not
distinguish between errors and informative messages, so the message
"Failed to transfer and install application, trying old way"
was added as an error. Errors in the Issues view also make Qt Creator
pop up the question if the user wants to continue with starting the
application even though there are errors, which is wrong and annoying
for that message.

Split messages from iostool into errors and "normal" messages. Normal
messages are not posted in the Issues view and use the "normal" font for
the text in the output view.

Fixes: QTCREATORBUG-31811
Change-Id: I99b456b408585440028f5211195d205cfeb54f09
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
Eike Ziller
2024-10-15 15:02:36 +02:00
parent ec4537dc01
commit 907c0a1401
9 changed files with 65 additions and 38 deletions

View File

@@ -54,6 +54,7 @@ public:
int progress, int maxProgress, const QString &info) {
emit progressValueChanged(progress * 100 / maxProgress, info);
});
connect(m_toolHandler.get(), &IosToolHandler::message, this, &IosTransfer::message);
connect(
m_toolHandler.get(),
&IosToolHandler::errorMsg,
@@ -85,6 +86,7 @@ public:
signals:
void done(DoneResult result);
void progressValueChanged(int progress, const QString &info); // progress in %
void message(const QString &message);
void errorMessage(const QString &message);
private:
@@ -253,6 +255,9 @@ GroupItem IosDeployStep::runRecipe()
transfer.setExpectSuccess(checkProvisioningProfile());
emit progress(0, transferringMessage);
connect(&transfer, &IosTransfer::progressValueChanged, this, &IosDeployStep::progress);
connect(&transfer, &IosTransfer::message, this, [this](const QString &message) {
emit addOutput(message, OutputFormat::NormalMessage);
});
connect(&transfer, &IosTransfer::errorMessage, this, [this](const QString &message) {
emit addOutput(message, OutputFormat::ErrorMessage);
});

View File

@@ -421,6 +421,7 @@ private:
void handleGotInferiorPid(Ios::IosToolHandler *handler, const FilePath &bundlePath,
const QString &deviceId, qint64 pid);
void handleAppOutput(Ios::IosToolHandler *handler, const QString &output);
void handleMessage(const QString &msg);
void handleErrorMsg(Ios::IosToolHandler *handler, const QString &msg);
void handleToolExited(Ios::IosToolHandler *handler, int code);
void handleFinished(Ios::IosToolHandler *handler);
@@ -529,8 +530,8 @@ void IosRunner::start()
m_toolHandler = new IosToolHandler(m_deviceType, this);
connect(m_toolHandler, &IosToolHandler::appOutput,
this, &IosRunner::handleAppOutput);
connect(m_toolHandler, &IosToolHandler::errorMsg,
this, &IosRunner::handleErrorMsg);
connect(m_toolHandler, &IosToolHandler::message, this, &IosRunner::handleMessage);
connect(m_toolHandler, &IosToolHandler::errorMsg, this, &IosRunner::handleErrorMsg);
connect(m_toolHandler, &IosToolHandler::gotServerPorts,
this, &IosRunner::handleGotServerPorts);
connect(m_toolHandler, &IosToolHandler::gotInferiorPid,
@@ -627,6 +628,16 @@ void IosRunner::handleAppOutput(IosToolHandler *handler, const QString &output)
appendMessage(output, StdOutFormat);
}
void IosRunner::handleMessage(const QString &msg)
{
QString res(msg);
QRegularExpression qmlPortRe("QML Debugger: Waiting for connection on port ([0-9]+)...");
const QRegularExpressionMatch match = qmlPortRe.match(msg);
if (match.hasMatch() && m_qmlServerPort.isValid())
res.replace(match.captured(1), QString::number(m_qmlServerPort.number()));
appendMessage(res, StdOutFormat);
}
void IosRunner::handleErrorMsg(IosToolHandler *handler, const QString &msg)
{
Q_UNUSED(handler)
@@ -640,11 +651,6 @@ void IosRunner::handleErrorMsg(IosToolHandler *handler, const QString &msg)
TaskHub::addTask(DeploymentTask(Task::Error, message));
res.replace(lockedErr, message);
}
QRegularExpression qmlPortRe("QML Debugger: Waiting for connection on port ([0-9]+)...");
const QRegularExpressionMatch match = qmlPortRe.match(msg);
if (match.hasMatch() && m_qmlServerPort.isValid())
res.replace(match.captured(1), QString::number(m_qmlServerPort.number()));
appendMessage(res, StdErrFormat);
}

View File

@@ -93,6 +93,7 @@ signals:
struct ParserState {
enum Kind {
Msg,
Error,
DeviceId,
Key,
Value,
@@ -119,6 +120,7 @@ struct ParserState {
bool collectChars() {
switch (kind) {
case Msg:
case Error:
case DeviceId:
case Key:
case Value:
@@ -386,6 +388,8 @@ void IosDeviceToolHandlerPrivate::processXml()
const auto elName = outputParser.name();
if (elName == QLatin1String("msg")) {
stack.append(ParserState(ParserState::Msg));
} else if (elName == QLatin1String("error")) {
stack.append(ParserState(ParserState::Error));
} else if (elName == QLatin1String("exit")) {
stack.append(ParserState(ParserState::Exit));
toolExited(outputParser.attributes().value(QLatin1String("code"))
@@ -459,8 +463,10 @@ void IosDeviceToolHandlerPrivate::processXml()
stack.removeLast();
switch (p.kind) {
case ParserState::Msg:
errorMsg(p.chars);
emit q->message(p.chars);
break;
case ParserState::Error:
errorMsg(p.chars);
case ParserState::DeviceId:
if (m_deviceId.isEmpty())
m_deviceId = p.chars;

View File

@@ -62,6 +62,7 @@ signals:
void deviceInfo(Ios::IosToolHandler *handler, const QString &deviceId,
const Ios::IosToolHandler::Dict &info);
void appOutput(Ios::IosToolHandler *handler, const QString &output);
void message(const QString &msg);
void errorMsg(Ios::IosToolHandler *handler, const QString &msg);
void toolExited(Ios::IosToolHandler *handler, int code);
void finished(Ios::IosToolHandler *handler);

View File

@@ -218,6 +218,7 @@ public:
void startDeviceLookup(int timeout);
bool connectToPort(quint16 port, ServiceSocket *fd) override;
int qmljsDebugPort() const override;
void addMessage(const QString &msg);
void addError(const QString &msg);
bool writeAll(ServiceSocket fd, const char *cmd, qptrdiff len = -1);
bool mountDeveloperDiskImage();
@@ -957,6 +958,11 @@ void CommandSession::startDeviceLookup(int timeout)
this);
}
void CommandSession::addMessage(const QString &msg)
{
IosDeviceManager::instance()->message(msg);
}
void CommandSession::addError(const QString &msg)
{
qCCritical(loggingCategory) << "CommandSession ERROR:" << msg;
@@ -1303,7 +1309,7 @@ bool AppOpSession::installApp()
bool success = false;
if (device) {
if (!installAppNew()) {
addError(QString::fromLatin1(
addMessage(QString::fromLatin1(
"Failed to transfer and install application, trying old way ..."));
const CFUrl_t bundleUrl(QUrl::fromLocalFile(bundlePath).toCFURL());

View File

@@ -58,6 +58,7 @@ signals:
Ios::DeviceSession *deviceSession);
void deviceInfo(const QString &deviceId, const Ios::IosDeviceManager::Dict &info);
void appOutput(const QString &output);
void message(const QString &msg);
void errorMsg(const QString &msg);
private:

View File

@@ -92,7 +92,7 @@ void IosTool::run(const QStringList &args)
bool ok = false;
timeout = cmdLineParser.value("timeout").toInt(&ok);
if (!ok || timeout < 0) {
writeMsg("timeout value should be an integer");
writeError("timeout value should be an integer");
printHelp = true;
}
}
@@ -118,7 +118,8 @@ void IosTool::run(const QStringList &args)
connect(manager, &IosDeviceManager::didStartApp, this, &IosTool::didStartApp);
connect(manager, &IosDeviceManager::deviceInfo, this, &IosTool::deviceInfo);
connect(manager, &IosDeviceManager::appOutput, this, &IosTool::appOutput);
connect(manager, &IosDeviceManager::errorMsg, this, &IosTool::errorMsg);
connect(manager, &IosDeviceManager::message, this, &IosTool::writeMsg);
connect(manager, &IosDeviceManager::errorMsg, this, &IosTool::writeError);
manager->watchDevices();
const QRegularExpression qmlPortRe(QLatin1String("-qmljsdebugger=port:([0-9]+)"));
for (const QString &arg : extraArgs) {
@@ -233,12 +234,12 @@ void IosTool::didStartApp(const QString &bundlePath, const QString &deviceId,
return;
}
if (gdbFd <= 0) {
writeMsg("no gdb connection");
writeError("no gdb connection");
doExit(-2);
return;
}
if (m_requestedOperation != IosDeviceManager::InstallAndRun && m_requestedOperation != IosDeviceManager::Run) {
writeMsg(QString::fromLatin1("unexpected appOp value %1").arg(m_requestedOperation));
writeError(QString::fromLatin1("unexpected appOp value %1").arg(m_requestedOperation));
doExit(-3);
return;
}
@@ -283,15 +284,15 @@ void IosTool::didStartApp(const QString &bundlePath, const QString &deviceId,
}
}
void IosTool::writeMsg(const char *msg)
{
writeMsg(QString::fromLatin1(msg));
}
void IosTool::writeMsg(const QString &msg)
{
writeMessageElement(msg, "msg");
}
void IosTool::writeMessageElement(const QString &msg, const QString &element)
{
QMutexLocker l(&m_xmlMutex);
m_xmlWriter.writeStartElement(QLatin1String("msg"));
m_xmlWriter.writeStartElement(element);
writeTextInElement(msg);
m_xmlWriter.writeCharacters(QLatin1String("\n"));
m_xmlWriter.writeEndElement();
@@ -380,15 +381,15 @@ void IosTool::readStdin()
int c = getchar();
if (c == 'k') {
QMetaObject::invokeMethod(this, "stopGdbRunner");
errorMsg(QLatin1String("iostool: Killing inferior.\n"));
writeError(QLatin1String("iostool: Killing inferior.\n"));
} else if (c != EOF) {
errorMsg(QLatin1String("iostool: Unexpected character in stdin, stop listening.\n"));
writeError(QLatin1String("iostool: Unexpected character in stdin, stop listening.\n"));
}
}
void IosTool::errorMsg(const QString &msg)
void IosTool::writeError(const QString &msg)
{
writeMsg(msg);
writeMessageElement(msg, "error");
}
void IosTool::stopGdbRunner()

View File

@@ -27,17 +27,17 @@ public:
virtual ~IosTool();
void run(const QStringList &args);
void doExit(int errorCode = 0);
void writeMsg(const char *msg);
void writeMsg(const QString &msg);
void stopXml(int errorCode);
void writeTextInElement(const QString &output);
void stopRelayServers(int errorCode = 0);
void writeMaybeBin(const QString &extraMsg, const char *msg, quintptr len);
void errorMsg(const QString &msg);
void writeError(const QString &msg);
Q_INVOKABLE void stopGdbRunner();
bool echoRelays() const { return m_echoRelays; }
private:
void writeMessageElement(const QString &msg, const QString &element);
void stopGdbRunner2();
void isTransferringApp(const QString &bundlePath, const QString &deviceId, int progress,
const QString &info);

View File

@@ -69,7 +69,7 @@ void Relayer::handleSocketHasData(int socket)
m_serverNotifier->setEnabled(true);
return;
}
iosTool()->errorMsg(qt_error_string(errno));
iosTool()->writeError(qt_error_string(errno));
close(socket);
iosTool()->stopRelayServers(-1);
return;
@@ -86,7 +86,7 @@ void Relayer::handleSocketHasData(int socket)
while (true) {
qint64 writtenNow = m_clientSocket->write(buf + int(pos), rRead);
if (writtenNow == -1) {
iosTool()->writeMsg(m_clientSocket->errorString());
iosTool()->writeError(m_clientSocket->errorString());
iosTool()->stopRelayServers(-1);
return;
}
@@ -110,7 +110,7 @@ void Relayer::handleClientHasData()
toRead = sizeof(buf)-1;
qint64 rRead = m_clientSocket->read(buf, toRead);
if (rRead == -1) {
iosTool()->errorMsg(m_clientSocket->errorString());
iosTool()->writeError(m_clientSocket->errorString());
iosTool()->stopRelayServers();
return;
}
@@ -137,7 +137,7 @@ void Relayer::handleClientHasData()
}
continue;
}
iosTool()->errorMsg(qt_error_string(errno));
iosTool()->writeError(qt_error_string(errno));
iosTool()->stopRelayServers();
return;
}
@@ -157,7 +157,7 @@ void Relayer::handleClientHasData()
void Relayer::handleClientHasError(QAbstractSocket::SocketError error)
{
iosTool()->errorMsg(tr("iOS Debugging connection to creator failed with error %1").arg(error));
iosTool()->writeError(tr("iOS debugging connection failed with error %1").arg(error));
server()->removeRelayConnection(this);
}
@@ -207,7 +207,7 @@ RemotePortRelayer::RemotePortRelayer(QmlRelayServer *parent, QTcpSocket *clientS
void RemotePortRelayer::tryRemoteConnect()
{
iosTool()->errorMsg(QLatin1String("tryRemoteConnect"));
iosTool()->writeMsg(QLatin1String("tryRemoteConnect"));
if (m_serverFileDescriptor > 0)
return;
ServiceSocket ss;
@@ -216,14 +216,15 @@ void RemotePortRelayer::tryRemoteConnect()
return;
if (grServer->m_deviceSession->connectToPort(grServer->m_remotePort, &ss)) {
if (ss > 0) {
iosTool()->errorMsg(QString::fromLatin1("tryRemoteConnect *succeeded* on remote port %1")
iosTool()->writeMsg(
QString::fromLatin1("tryRemoteConnect *succeeded* on remote port %1")
.arg(grServer->m_remotePort));
startRelay(ss);
emit didConnect(grServer);
return;
}
}
iosTool()->errorMsg(QString::fromLatin1("tryRemoteConnect *failed* on remote port %1")
iosTool()->writeMsg(QString::fromLatin1("tryRemoteConnect *failed* on remote port %1")
.arg(grServer->m_remotePort));
m_remoteConnectTimer.start();
}
@@ -277,7 +278,7 @@ IosTool *RelayServer::iosTool() const
void RelayServer::handleNewRelayConnection()
{
iosTool()->errorMsg(QLatin1String("handleNewRelayConnection"));
iosTool()->writeMsg(QLatin1String("handleNewRelayConnection"));
newRelayConnection();
}
@@ -318,7 +319,7 @@ QmlRelayServer::QmlRelayServer(IosTool *parent, int remotePort,
m_remotePort(remotePort),
m_deviceSession(deviceSession)
{
parent->errorMsg(QLatin1String("created qml server"));
parent->writeMsg(QLatin1String("created qml server"));
}
@@ -327,7 +328,7 @@ void QmlRelayServer::newRelayConnection()
QTcpSocket *clientSocket = m_ipv4Server.hasPendingConnections()
? m_ipv4Server.nextPendingConnection() : m_ipv6Server.nextPendingConnection();
if (clientSocket) {
iosTool()->errorMsg(QString::fromLatin1("setting up relayer for new connection"));
iosTool()->writeMsg(QString::fromLatin1("setting up relayer for new connection"));
RemotePortRelayer *newConnection = new RemotePortRelayer(this, clientSocket);
m_connections.append(newConnection);
newConnection->tryRemoteConnect();