Fix crashes in devices

This commit is contained in:
Jonas Kvinge 2019-01-05 23:11:16 +01:00
parent d5fffc3641
commit a06de35aa5
9 changed files with 44 additions and 19 deletions

View File

@ -68,7 +68,9 @@ ConnectedDevice::ConnectedDevice(const QUrl &url, DeviceLister *lister, const QS
}
ConnectedDevice::~ConnectedDevice() { backend_->deleteLater(); }
ConnectedDevice::~ConnectedDevice() {
backend_->deleteLater();
}
void ConnectedDevice::InitBackendDirectory(const QString &mount_point, bool first_time, bool rewrite_path) {

View File

@ -35,6 +35,8 @@
#include "devicelister.h"
#include "core/logging.h"
DeviceLister::DeviceLister() : thread_(nullptr) {}
DeviceLister::~DeviceLister() {

View File

@ -75,7 +75,7 @@ class DeviceLister : public QObject {
virtual void UpdateDeviceFreeSpace(const QString &id) = 0;
virtual void ShutDown() {}
signals:
signals:
void DeviceAdded(const QString &id);
void DeviceRemoved(const QString &id);
void DeviceChanged(const QString &id);

View File

@ -108,7 +108,7 @@ DeviceManager::DeviceManager(Application *app, QObject *parent)
backend_->moveToThread(app_->database()->thread());
backend_->Init(app_->database());
// This reads from the database and contends on the database mutex, which can be very slow on startup.
// This reads from the database and contents on the database mutex, which can be very slow on startup.
ConcurrentRun::Run<void>(&thread_pool_, bind(&DeviceManager::LoadAllDevices, this));
// This proxy model only shows connected devices
@ -179,13 +179,14 @@ QVariant DeviceManager::data(const QModelIndex &index, int role) const {
if (!index.isValid() || index.column() != 0) return QVariant();
const DeviceInfo *info = IndexToItem(index);
if (!info) return QVariant();
switch (role) {
case Qt::DisplayRole: {
QString text;
if (!info->friendly_name_.isEmpty())
text = info->friendly_name_;
else
else if (info->BestBackend())
text = info->BestBackend()->unique_id_;
if (info->size_)
@ -210,6 +211,7 @@ QVariant DeviceManager::data(const QModelIndex &index, int role) const {
return info->friendly_name_;
case Role_UniqueId:
if (!info->BestBackend()) return QString();
return info->BestBackend()->unique_id_;
case Role_IconName:
@ -221,11 +223,11 @@ QVariant DeviceManager::data(const QModelIndex &index, int role) const {
case Role_FreeSpace:
case MusicStorage::Role_FreeSpace:
return info->BestBackend()->lister_ ? info->BestBackend()->lister_->DeviceFreeSpace(info->BestBackend()->unique_id_) : QVariant();
return ((info->BestBackend() && info->BestBackend()->lister_) ? info->BestBackend()->lister_->DeviceFreeSpace(info->BestBackend()->unique_id_) : QVariant());
case Role_State:
if (info->device_) return State_Connected;
if (info->BestBackend()->lister_) {
if (info->BestBackend() && info->BestBackend()->lister_) {
if (info->BestBackend()->lister_->DeviceNeedsMount(info->BestBackend()->unique_id_)) return State_NotMounted;
return State_NotConnected;
}
@ -243,9 +245,9 @@ QVariant DeviceManager::data(const QModelIndex &index, int role) const {
case MusicStorage::Role_StorageForceConnect:
if (!info->device_) {
if (info->database_id_ == -1 && !info->BestBackend()->lister_->DeviceNeedsMount(info->BestBackend()->unique_id_)) {
if (info->database_id_ == -1 && info->BestBackend() && !info->BestBackend()->lister_->DeviceNeedsMount(info->BestBackend()->unique_id_)) {
if (info->BestBackend()->lister_->AskForScan(info->BestBackend()->unique_id_)) {
if (info->BestBackend() && info->BestBackend()->lister_->AskForScan(info->BestBackend()->unique_id_)) {
std::unique_ptr<QMessageBox> dialog(new QMessageBox(QMessageBox::Information, tr("Connect device"), tr("This is the first time you have connected this device. Strawberry will now scan the device to find music files - this may take some time."), QMessageBox::Cancel));
QPushButton *connect = dialog->addButton(tr("Connect device"), QMessageBox::AcceptRole);
dialog->exec();
@ -282,6 +284,7 @@ QVariant DeviceManager::data(const QModelIndex &index, int role) const {
default:
return QVariant();
}
}
void DeviceManager::AddLister(DeviceLister *lister) {
@ -329,8 +332,9 @@ int DeviceManager::FindDeviceByUrl(const QList<QUrl> &urls) const {
void DeviceManager::PhysicalDeviceAdded(const QString &id) {
DeviceLister *lister = qobject_cast<DeviceLister*>(sender());
if (!lister) return;
qLog(Info) << "Device added:" << id;
qLog(Info) << "Device added:" << id << lister->DeviceUniqueIDs();
// Do we have this device already?
int i = FindDeviceById(id);
@ -562,12 +566,15 @@ DeviceLister *DeviceManager::GetLister(int row) const {
void DeviceManager::Disconnect(int row) {
DeviceInfo *info = devices_[row];
if (!info->device_) // Already disconnected
if (!info || !info->device_)
return;
info->device_.reset();
emit DeviceDisconnected(row);
QModelIndex index = ItemToIndex(info);
if (!index.isValid()) return;
emit dataChanged(index, index);
}
@ -700,6 +707,8 @@ void DeviceManager::DeviceSongCountUpdated(int count) {
if (row == -1) return;
QModelIndex index = ItemToIndex(devices_[row]);
if (!index.isValid()) return;
emit dataChanged(index, index);
}
@ -716,8 +725,14 @@ DeviceInfo *DeviceManager::ItemFromRow(int row) {
QString DeviceManager::DeviceNameByID(QString unique_id) {
int row = FindDeviceById(unique_id);
if (row == -1) return QString();
DeviceInfo *info = devices_[row];
if (!info) return QString();
QModelIndex index = ItemToIndex(info);
if (!index.isValid()) return QString();
return data(index, DeviceManager::Role_FriendlyName).toString();
}

View File

@ -324,6 +324,7 @@ void DeviceView::DeviceConnected(int row) {
void DeviceView::DeviceDisconnected(int row) {
DeviceInfo *info = app_->device_manager()->ItemFromRow(row);
if (!info) return;
QModelIndex index = app_->device_manager()->ItemToIndex(info);
merged_model_->RemoveSubModel(sort_model_->mapFromSource(index));
}

View File

@ -26,6 +26,8 @@
#include <QUrl>
#include "core/application.h"
#include "core/logging.h"
#include "collection/collectionbackend.h"
#include "collection/collectionmodel.h"
#include "collection/collectionwatcher.h"
@ -42,6 +44,7 @@ FilesystemDevice::FilesystemDevice(const QUrl &url, DeviceLister *lister, const
watcher_->moveToThread(watcher_thread_);
watcher_thread_->start(QThread::IdlePriority);
qLog(Debug) << __PRETTY_FUNCTION__ << unique_id;
watcher_->set_device_name(manager->DeviceNameByID(unique_id));
watcher_->set_backend(backend_);
watcher_->set_task_manager(app_->task_manager());

View File

@ -62,11 +62,7 @@ bool GioLister::DeviceInfo::is_suitable() const {
if (filesystem_type.isEmpty()) return true;
return filesystem_type != "udf" &&
filesystem_type != "smb" &&
filesystem_type != "cifs" &&
filesystem_type != "ssh" &&
filesystem_type != "isofs";
return filesystem_type != "udf" && filesystem_type != "smb" && filesystem_type != "cifs" && filesystem_type != "ssh" && filesystem_type != "isofs";
}
@ -336,9 +332,8 @@ void GioLister::MountAdded(GMount *mount) {
if (!old_id.isEmpty())
emit DeviceChanged(old_id);
else {
else
emit DeviceAdded(info.unique_id());
}
}
@ -527,6 +522,7 @@ void GioLister::UnmountDevice(const QString &id) {
return;
}
}
else return;
if (g_mount_can_eject(info.mount)) {
g_mount_eject_with_operation(info.mount, G_MOUNT_UNMOUNT_NONE, nullptr, nullptr, (GAsyncReadyCallback)MountEjectFinished, nullptr);

View File

@ -77,6 +77,13 @@ void GPodDevice::LoadFinished(Itdb_iTunesDB *db) {
db_ = db;
db_wait_cond_.wakeAll();
if (loader_thread_) {
loader_thread_->quit();
loader_thread_->wait(1000);
loader_thread_->deleteLater();
loader_thread_ = nullptr;
}
loader_->deleteLater();
loader_ = nullptr;

View File

@ -120,8 +120,7 @@ QString Udisks2Lister::MakeFriendlyName(const QString &id) {
QList<QUrl> Udisks2Lister::MakeDeviceUrls(const QString &id) {
QReadLocker locker(&device_data_lock_);
if (!device_data_.contains(id)) return QList<QUrl>();
return QList<QUrl>() << QUrl::fromLocalFile(
device_data_[id].mount_paths.at(0));
return QList<QUrl>() << QUrl::fromLocalFile(device_data_[id].mount_paths.at(0));
}
void Udisks2Lister::UnmountDevice(const QString &id) {