Qt for HarmonyOS/qtohosextras doc/Want FDs Sender Example - main.cpp
< Qt for HarmonyOS / qtohosextras doc
Want FDs Sender Example - main.cpp
// Copyright (C) 2026 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QApplication>
#include <QFile>
#include <QFileDialog>
#include <QFormLayout>
#include <QHBoxLayout>
#include <QJsonDocument>
#include <QJsonObject>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QSharedPointer>
#include <QTextEdit>
#include <QVBoxLayout>
#include <QWidget>
#include <QtOhosExtras>
#include <cerrno>
#include <cstring>
#include <sys/stat.h>
namespace {
class FdSenderWindow : public QWidget
{
public:
explicit FdSenderWindow(QWidget *parent = nullptr);
private:
void sendWant();
void appendLog(const QString &message);
void selectFiles();
QLineEdit *m_bundleNameEdit;
QLineEdit *m_moduleNameEdit;
QLineEdit *m_abilityNameEdit;
QLabel *m_pathsLabel;
QTextEdit *m_logEdit;
QStringList m_selectedFiles;
};
FdSenderWindow::FdSenderWindow(QWidget *parent)
: QWidget(parent)
, m_bundleNameEdit(new QLineEdit(QStringLiteral("com.ohos.wantfdsreceiver"), this))
, m_moduleNameEdit(new QLineEdit(QStringLiteral("entry"), this))
, m_abilityNameEdit(new QLineEdit(QStringLiteral("QAbility"), this))
, m_pathsLabel(new QLabel(QStringLiteral("<none>"), this))
, m_logEdit(new QTextEdit(this))
{
setWindowTitle(QStringLiteral("Want FD Sender"));
auto *mainLayout = new QVBoxLayout(this);
auto *formLayout = new QFormLayout();
formLayout->addRow(QStringLiteral("bundleName:"), m_bundleNameEdit);
formLayout->addRow(QStringLiteral("moduleName:"), m_moduleNameEdit);
formLayout->addRow(QStringLiteral("abilityName:"), m_abilityNameEdit);
auto *filePathLayout = new QHBoxLayout();
auto *browseButton = new QPushButton(QStringLiteral("Browse..."), this);
m_pathsLabel->setWordWrap(true);
filePathLayout->addWidget(m_pathsLabel, 1);
filePathLayout->addWidget(browseButton);
auto *filePathWidget = new QWidget(this);
filePathWidget->setLayout(filePathLayout);
formLayout->addRow(QStringLiteral("paths:"), filePathWidget);
QObject::connect(browseButton, &QPushButton::clicked, this, &FdSenderWindow::selectFiles);
auto *sendButton = new QPushButton(QStringLiteral("Send FD"), this);
QObject::connect(sendButton, &QPushButton::clicked, this, &FdSenderWindow::sendWant);
mainLayout->addLayout(formLayout);
mainLayout->addWidget(sendButton);
m_logEdit->setReadOnly(true);
mainLayout->addWidget(m_logEdit);
}
void FdSenderWindow::appendLog(const QString &message)
{
m_logEdit->append(message);
}
void FdSenderWindow::selectFiles()
{
const QStringList filePaths = QFileDialog::getOpenFileNames(this, QStringLiteral("Select Files"));
if (filePaths.isEmpty()) {
return;
}
m_selectedFiles = filePaths;
m_pathsLabel->setText(filePaths.join(QLatin1Char('\n')));
}
void FdSenderWindow::sendWant()
{
const QString bundleName = m_bundleNameEdit->text().trimmed();
const QString abilityName = m_abilityNameEdit->text().trimmed();
const QStringList filePaths = m_selectedFiles;
if (bundleName.isEmpty() || abilityName.isEmpty()) {
appendLog(QStringLiteral("status: missing bundleName/abilityName"));
return;
}
if (filePaths.isEmpty()) {
appendLog(QStringLiteral("status: no selected files"));
return;
}
QtOhosExtras::QOhosWant want;
want.bundleName = bundleName;
want.moduleName = m_moduleNameEdit->text().trimmed();
want.abilityName = abilityName;
QList<QSharedPointer<QFile>> openFiles;
QStringList fdDetails;
int openedCount = 0;
for (const auto &filePath : filePaths) {
auto file = QSharedPointer<QFile>::create(filePath);
if (!file->open(QIODevice::ReadOnly)) {
appendLog(QStringLiteral("fd_open: path=%1 result=error error=%2").arg(filePath, file->errorString()));
continue;
}
const int fd = file->handle();
if (fd < 0) {
appendLog(QStringLiteral("fd_open: path=%1 result=error error=invalid_fd").arg(filePath));
continue;
}
const QString fdKey = QStringLiteral("keyFd%1").arg(openedCount);
want.fds.insert(fdKey, fd);
struct stat statInfo;
const int fstatResult = ::fstat(fd, &statInfo);
const int fstatErrno = errno;
if (fstatResult == 0) {
fdDetails.append(
QStringLiteral("fd_info: key=%1 fd=%2 path=%3 dev=%4 ino=%5")
.arg(fdKey)
.arg(fd)
.arg(filePath)
.arg(static_cast<qulonglong>(statInfo.st_dev))
.arg(static_cast<qulonglong>(statInfo.st_ino)));
} else {
fdDetails.append(
QStringLiteral("fd_detail: key=%1 fd=%2 path=%3 stat_error=%4 message=%5")
.arg(fdKey)
.arg(fd)
.arg(filePath)
.arg(fstatErrno)
.arg(QString::fromLocal8Bit(strerror(fstatErrno))));
}
openFiles.append(file);
++openedCount;
}
if (openedCount == 0) {
appendLog(QStringLiteral("status: no_open_fds"));
return;
}
const auto operationStatus = QtOhosExtras::startAbility(want);
appendLog(QStringLiteral("startAbility: success=%1").arg(!operationStatus.isNull() && operationStatus->success()));
for (const auto &detail : fdDetails) {
appendLog(detail);
}
}
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
FdSenderWindow window;
window.show();
return app.exec();
}