File indexing completed on 2024-10-06 10:50:49

0001 /*
0002  * This file is part of the KDE project
0003  *
0004  * SPDX-FileCopyrightText: 2010-2011 Alejandro Fiestas Olivares <afiestas@kde.org>
0005  * SPDX-FileCopyrightText: 2010-2011 UFO Coders <info@ufocoders.com>
0006  *
0007  * SPDX-License-Identifier: LGPL-2.0-or-later
0008  */
0009 
0010 #include "sendfilesjob.h"
0011 #include "bluedevil_sendfile.h"
0012 
0013 #include <QDBusObjectPath>
0014 #include <QFile>
0015 #include <QUrl>
0016 
0017 #include <KLocalizedString>
0018 
0019 #include <BluezQt/Device>
0020 #include <BluezQt/InitObexManagerJob>
0021 #include <BluezQt/ObexManager>
0022 #include <BluezQt/ObexObjectPush>
0023 #include <BluezQt/PendingCall>
0024 
0025 SendFilesJob::SendFilesJob(const QStringList &files, BluezQt::DevicePtr device, const QDBusObjectPath &session, QObject *parent)
0026     : KJob(parent)
0027     , m_files(files)
0028     , m_progress(0)
0029     , m_totalSize(0)
0030     , m_speedBytes(0)
0031     , m_currentFileSize(0)
0032     , m_currentFileProgress(0)
0033     , m_device(device)
0034 {
0035     qCDebug(BLUEDEVIL_SENDFILE_LOG) << "SendFilesJob:" << files;
0036 
0037     for (const QString &filePath : files) {
0038         QFile file(filePath);
0039         m_filesSizes << file.size();
0040         m_totalSize += file.size();
0041     }
0042 
0043     setCapabilities(Killable);
0044 
0045     m_objectPush = new BluezQt::ObexObjectPush(session, this);
0046 }
0047 
0048 void SendFilesJob::start()
0049 {
0050     QMetaObject::invokeMethod(this, "doStart", Qt::QueuedConnection);
0051 }
0052 
0053 bool SendFilesJob::doKill()
0054 {
0055     if (m_transfer) {
0056         m_transfer->cancel();
0057     }
0058     return true;
0059 }
0060 
0061 void SendFilesJob::doStart()
0062 {
0063     qCDebug(BLUEDEVIL_SENDFILE_LOG) << "SendFilesJob-DoStart";
0064 
0065     setTotalAmount(Files, m_files.count());
0066     setTotalAmount(Bytes, m_totalSize);
0067     setProcessedAmount(Bytes, 0);
0068 
0069     nextJob();
0070 }
0071 
0072 void SendFilesJob::nextJob()
0073 {
0074     qCDebug(BLUEDEVIL_SENDFILE_LOG) << "SendFilesJob-NextJob";
0075 
0076     m_transfer.clear();
0077     m_currentFile = m_files.takeFirst();
0078     m_currentFileSize = m_filesSizes.takeFirst();
0079     // Starts at 1 file.
0080     setProcessedAmount(Files, totalAmount(Files) - m_files.count());
0081 
0082     Q_EMIT description(this,
0083                        i18n("Sending file over Bluetooth"),
0084                        QPair<QString, QString>(i18nc("File transfer origin", "From"), m_currentFile),
0085                        QPair<QString, QString>(i18nc("File transfer destination", "To"), m_device->name()));
0086 
0087     BluezQt::PendingCall *call = m_objectPush->sendFile(m_currentFile);
0088     connect(call, &BluezQt::PendingCall::finished, this, &SendFilesJob::sendFileFinished);
0089 }
0090 
0091 void SendFilesJob::sendFileFinished(BluezQt::PendingCall *call)
0092 {
0093     if (call->error()) {
0094         qCWarning(BLUEDEVIL_SENDFILE_LOG) << "Error sending file" << call->errorText();
0095         setError(UserDefinedError);
0096         setErrorText(call->errorText());
0097         emitResult();
0098         return;
0099     }
0100 
0101     m_transfer = call->value().value<BluezQt::ObexTransferPtr>();
0102     connect(m_transfer.data(), &BluezQt::ObexTransfer::statusChanged, this, &SendFilesJob::statusChanged);
0103     connect(m_transfer.data(), &BluezQt::ObexTransfer::transferredChanged, this, &SendFilesJob::transferredChanged);
0104 }
0105 
0106 void SendFilesJob::jobDone()
0107 {
0108     qCDebug(BLUEDEVIL_SENDFILE_LOG) << "SendFilesJob-JobDone";
0109 
0110     m_speedBytes = 0;
0111     m_currentFileSize = 0;
0112     m_currentFileProgress = 0;
0113 
0114     if (!m_files.isEmpty()) {
0115         nextJob();
0116         return;
0117     }
0118 
0119     emitResult();
0120 }
0121 
0122 void SendFilesJob::transferredChanged(quint64 transferred)
0123 {
0124     // qCDebug(SENDFILE) << "SendFilesJob-Transferred" << transferred;
0125 
0126     // If at least 1 second has passed since last update
0127     int secondsSinceLastTime = m_time.secsTo(QTime::currentTime());
0128     if (secondsSinceLastTime > 0) {
0129         float speed = (transferred - m_speedBytes) / secondsSinceLastTime;
0130         emitSpeed(speed);
0131 
0132         m_time = QTime::currentTime();
0133         m_speedBytes = transferred;
0134     }
0135 
0136     progress(transferred);
0137 }
0138 
0139 void SendFilesJob::statusChanged(BluezQt::ObexTransfer::Status status)
0140 {
0141     switch (status) {
0142     case BluezQt::ObexTransfer::Active:
0143         qCDebug(BLUEDEVIL_SENDFILE_LOG) << "SendFilesJob-Transfer Active";
0144         m_time = QTime::currentTime();
0145         break;
0146 
0147     case BluezQt::ObexTransfer::Complete:
0148         qCDebug(BLUEDEVIL_SENDFILE_LOG) << "SendFilesJob-Transfer Complete";
0149         jobDone();
0150         break;
0151 
0152     case BluezQt::ObexTransfer::Error:
0153         qCDebug(BLUEDEVIL_SENDFILE_LOG) << "SendFilesJob-Transfer Error";
0154         setError(UserDefinedError);
0155         setErrorText(i18n("Bluetooth transfer failed"));
0156         emitResult();
0157         break;
0158 
0159     default:
0160         qCWarning(BLUEDEVIL_SENDFILE_LOG) << "Not implemented status: " << status;
0161         break;
0162     }
0163 }
0164 
0165 void SendFilesJob::progress(quint64 transferBytes)
0166 {
0167     quint64 toAdd = transferBytes - m_currentFileProgress;
0168     m_currentFileProgress = transferBytes;
0169     m_progress += toAdd;
0170     setProcessedAmount(Bytes, m_progress);
0171 }