Skip to content

Commit

Permalink
refactor: improve disk type identification logic
Browse files Browse the repository at this point in the history
This commit refactors how different types of disks are identified and
handled. The changes include:

- Split isSystemDisk into more specific isBuiltInDisk and isDataDisk checks
- Improve system disk detection with better root partition handling
- Add clear distinction between built-in, system and data disks
- Optimize QVariantMap to QVariantHash conversion with helper method
- Update disk name generation and ordering logic

This makes the disk type identification more accurate and maintainable,
especially for system disks, data disks, and built-in disks.

Log:

Bug: https://pms.uniontech.com/bug-view-276749.html
  • Loading branch information
Johnson-zs committed Dec 26, 2024
1 parent be76dda commit 3f0d013
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 45 deletions.
2 changes: 1 addition & 1 deletion src/dfm-base/base/device/devicemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ QStringList DeviceManager::getAllBlockDevID(DeviceQueryOptions opts)
&& !data.value(DeviceProperty::kOptical).toBool())
continue;
if (opts.testFlag(DeviceQueryOption::kSystem)
&& !DeviceUtils::isSystemDisk(data))
&& !DeviceUtils::isBuiltInDisk(data))
continue;
if (opts.testFlag(DeviceQueryOption::kLoop)
&& !data.value(DeviceProperty::kIsLoopDevice).toBool())
Expand Down
4 changes: 2 additions & 2 deletions src/dfm-base/base/device/deviceproxymanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ void DeviceProxyManagerPrivate::initMounts()
mpt = mpt.endsWith("/") ? mpt : mpt + "/";
// FIXME(xust): fix later, the kRemovable is not always correct.
QWriteLocker lk(&lock);
if (info.value(DeviceProperty::kRemovable).toBool() && !DeviceUtils::isSystemDisk(info))
if (info.value(DeviceProperty::kRemovable).toBool() && !DeviceUtils::isBuiltInDisk(info))
externalMounts.insert(dev, mpt);
allMounts.insert(dev, mpt);
}
Expand Down Expand Up @@ -355,7 +355,7 @@ void DeviceProxyManagerPrivate::addMounts(const QString &id, const QString &mpt)
if (id.startsWith(kBlockDeviceIdPrefix)) {
auto &&info = q->queryBlockInfo(id);
if (info.value(GlobalServerDefines::DeviceProperty::kRemovable).toBool()
&& !DeviceUtils::isSystemDisk(info))
&& !DeviceUtils::isBuiltInDisk(info))
externalMounts.insert(id, p);
} else {
externalMounts.insert(id, p);
Expand Down
111 changes: 80 additions & 31 deletions src/dfm-base/base/device/deviceutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <QRegularExpressionMatch>

Check warning on line 24 in src/dfm-base/base/device/deviceutils.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QRegularExpressionMatch> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 24 in src/dfm-base/base/device/deviceutils.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QRegularExpressionMatch> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QMutex>

Check warning on line 25 in src/dfm-base/base/device/deviceutils.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QMutex> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 25 in src/dfm-base/base/device/deviceutils.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QMutex> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QSettings>

Check warning on line 26 in src/dfm-base/base/device/deviceutils.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QSettings> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 26 in src/dfm-base/base/device/deviceutils.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QSettings> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QDir>

Check warning on line 27 in src/dfm-base/base/device/deviceutils.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QDir> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 27 in src/dfm-base/base/device/deviceutils.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QDir> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <libmount.h>

Check warning on line 29 in src/dfm-base/base/device/deviceutils.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <libmount.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 29 in src/dfm-base/base/device/deviceutils.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <libmount.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <fstab.h>

Check warning on line 30 in src/dfm-base/base/device/deviceutils.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <fstab.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Check warning on line 30 in src/dfm-base/base/device/deviceutils.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <fstab.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
Expand Down Expand Up @@ -94,7 +95,7 @@ QUrl DeviceUtils::getSambaFileUriFromNative(const QUrl &url)
// /root/.gvfs/smb-share...../helloworld.txt
// /media/user/smbmounts/smb-share...../helloworld.txt
// ======> helloworld.txt
static const QRegularExpression prefix(R"(^/run/user/.*/gvfs/[^/]*/|^/root/.gvfs/[^/]*/|^/(?:run/)?media/.*/smbmounts/[^/]*/)");
static const QRegularExpression prefix(R"(^/run/user/.*/gvfs/[^/]*/|^/root/.gvfs/[^/]*/|^/(?:run/)?media/.*/smbmounts/[^/]*)");
QString fileName = fullPath.remove(prefix);
fileName.chop(1); // remove last '/'.

Expand Down Expand Up @@ -127,11 +128,9 @@ QString DeviceUtils::convertSuitableDisplayName(const QVariantMap &devInfo)
return alias;

QVariantMap clearInfo = devInfo.value(BlockAdditionalProperty::kClearBlockProperty).toMap();
QString mpt = clearInfo.value(kMountPoint, devInfo.value(kMountPoint).toString()).toString();
QString idLabel = clearInfo.value(kIdLabel, devInfo.value(kIdLabel).toString()).toString();
// NOTE(xust): removable/hintSystem is not always correct in some certain hardwares.
if (mpt == "/" || idLabel.startsWith("_dde_")) {
return nameOfSystemDisk(devInfo);
if (DeviceUtils::isBuiltInDisk(clearInfo.isEmpty() ? devInfo : clearDevInfo)) {
return nameOfBuiltInDisk(devInfo);
} else if (devInfo.value(kIsEncrypted).toBool()) {
return nameOfEncrypted(devInfo);
} else if (devInfo.value(kOpticalDrive).toBool()) {
Expand Down Expand Up @@ -368,7 +367,7 @@ QMap<QString, QString> DeviceUtils::fstabBindInfo()
return table;
}

QString DeviceUtils::nameOfSystemDisk(const QVariantMap &datas)
QString DeviceUtils::nameOfBuiltInDisk(const QVariantMap &datas)
{
QVariantMap clearInfo = datas.value(BlockAdditionalProperty::kClearBlockProperty).toMap();

Expand All @@ -378,7 +377,7 @@ QString DeviceUtils::nameOfSystemDisk(const QVariantMap &datas)
bool canPowerOff = datas.value(kCanPowerOff).toBool();

// get system disk name if there is no alias
if (mountPoint == "/")
if (DeviceUtils::isSystemDisk(clearInfo.isEmpty() ? datas : clearInfo))
return QObject::tr("System Disk");
if (!canPowerOff && !mountPoint.isEmpty()) {
if (label.startsWith("_dde_data"))
Expand Down Expand Up @@ -664,37 +663,84 @@ QString DeviceUtils::bindPathTransform(const QString &path, bool toDevice)
return bindPath;
}

bool DeviceUtils::isSystemDisk(const QVariantHash &devInfo)
bool DeviceUtils::isBuiltInDisk(const QVariantHash &devInfo)
{
if (!devInfo.contains(GlobalServerDefines::DeviceProperty::kHintSystem))
// 如果是可移除设备,则不是内置磁盘
if (devInfo.value(kCanPowerOff).toBool())
return false;

// 如果是光驱设备,则不是内置磁盘
if (devInfo.value(kOpticalDrive).toBool())
return false;

bool isSystem = devInfo.value(GlobalServerDefines::DeviceProperty::kHintSystem).toBool()
|| devInfo.value(GlobalServerDefines::DeviceProperty::kConnectionBus).toString() != "usb";
if (devInfo.value(GlobalServerDefines::DeviceProperty::kOpticalDrive).toBool())
isSystem = false;
// treat the siblings of root(/) device as System devices.
isSystem |= isSiblingOfRoot(devInfo);
return isSystem;
// 检查是否为系统相关磁盘
QString mpt = devInfo.value(kMountPoint).toString();
QString idLabel = devInfo.value(kIdLabel).toString();
if (mpt == QDir::rootPath() || idLabel.startsWith("_dde_"))
return true;

// 检查硬件特征
bool hintSystem = devInfo.value(kHintSystem).toBool();
QString bus = devInfo.value(kConnectionBus).toString();
if (hintSystem || bus != "usb")
return true;

// 检查是否为根设备的兄弟设备
return isSiblingOfRoot(devInfo);
}

bool DeviceUtils::isBuiltInDisk(const QVariantMap &devInfo)
{
return isBuiltInDisk(toHash(devInfo));
}

bool DeviceUtils::isSystemDisk(const QVariantHash &devInfo)
{
// 检查是否为根目录
QString mountPoint = devInfo.value(kMountPoint).toString();
if (mountPoint == QDir::rootPath())
return true;

// 特殊情况:Root[X]分区, A-B Recover
QString label = devInfo.value(kIdLabel).toString();
if (label.startsWith("Root") && mountPoint == "/sysroot")
return true;

return false;
}

bool DeviceUtils::isSystemDisk(const QVariantMap &devInfo)
{
QVariantHash hash;
QMapIterator<QString, QVariant> iter(devInfo);
while (iter.hasNext()) {
iter.next();
hash.insert(iter.key(), iter.value());
}
return isSystemDisk(hash);
return isSystemDisk(toHash(devInfo));
}

bool DeviceUtils::isDataDisk(const QVariantHash &devInfo)
{
// 如果是可移除设备,则不是数据盘
if (devInfo.value(kCanPowerOff).toBool())
return false;

// 如果是根目录,则不是数据盘
QString mountPoint = devInfo.value(kMountPoint).toString();
if (mountPoint == QDir::rootPath())
return false;

// 检查标签是否为数据盘标识
QString label = devInfo.value(kIdLabel).toString();
return label.startsWith("_dde_data");
}

bool DeviceUtils::isDataDisk(const QVariantMap &devInfo)
{
return isDataDisk(toHash(devInfo));
}

bool DeviceUtils::isSiblingOfRoot(const QVariantHash &devInfo)
{
static QString rootDrive;
static std::once_flag flg;
std::call_once(flg, [] {
const QString &rootDev = DeviceUtils::getMountInfo("/", false);
const QString &rootDev = DeviceUtils::getMountInfo(QDir::rootPath(), false);
const QString &rootDevId = DeviceUtils::getBlockDeviceId(rootDev);
const auto &data = DevProxyMng->queryBlockInfo(rootDevId);
rootDrive = data.value(GlobalServerDefines::DeviceProperty::kDrive).toString();
Expand All @@ -706,13 +752,7 @@ bool DeviceUtils::isSiblingOfRoot(const QVariantHash &devInfo)

bool DeviceUtils::isSiblingOfRoot(const QVariantMap &devInfo)
{
QVariantHash hash;
QMapIterator<QString, QVariant> iter(devInfo);
while (iter.hasNext()) {
iter.next();
hash.insert(iter.key(), iter.value());
}
return isSiblingOfRoot(hash);
return isSiblingOfRoot(toHash(devInfo));
}

bool DeviceUtils::findDlnfsPath(const QString &target, Compare func)
Expand Down Expand Up @@ -757,3 +797,12 @@ bool DeviceUtils::hasMatch(const QString &txt, const QString &rex)
QRegularExpressionMatch match = re.match(txt);
return match.hasMatch();
}

QVariantHash DeviceUtils::toHash(const QVariantMap &map)
{
QVariantHash hash;
hash.reserve(map.size());
for (auto it = map.constBegin(); it != map.constEnd(); ++it)
hash.insert(it.key(), it.value());
return hash;
}
7 changes: 6 additions & 1 deletion src/dfm-base/base/device/deviceutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class DeviceUtils

static QMap<QString, QString> fstabBindInfo();

static QString nameOfSystemDisk(const QVariantMap &datas);
static QString nameOfBuiltInDisk(const QVariantMap &datas);
static QString nameOfOptical(const QVariantMap &datas);
static QString nameOfEncrypted(const QVariantMap &datas);
static QString nameOfDefault(const QString &label, const quint64 &size);
Expand All @@ -78,15 +78,20 @@ class DeviceUtils
// otherwise convert the path to the mount point name
static QString bindPathTransform(const QString &path, bool toDevice);

static bool isBuiltInDisk(const QVariantHash &devInfo);
static bool isBuiltInDisk(const QVariantMap &devInfo);
static bool isSystemDisk(const QVariantHash &devInfo);
static bool isSystemDisk(const QVariantMap &devInfo);
static bool isDataDisk(const QVariantHash &devInfo);
static bool isDataDisk(const QVariantMap &devInfo);
static bool isSiblingOfRoot(const QVariantHash &devInfo);
static bool isSiblingOfRoot(const QVariantMap &devInfo);

private:
static bool hasMatch(const QString &txt, const QString &rex);
using Compare = std::function<bool(const QString &, const QString &)>;
static bool findDlnfsPath(const QString &target, Compare func);
static QVariantHash toHash(const QVariantMap &map);
};

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ bool SendToMenuScene::create(QMenu *parent)
QString mpt = data.value(DeviceProperty::kMountPoint).toString();
QString devDesc = data.value(DeviceProperty::kDevice).toString();

if (data.value(DeviceProperty::kOptical).toBool() || DeviceUtils::isSystemDisk(data)) {
if (data.value(DeviceProperty::kOptical).toBool() || DeviceUtils::isBuiltInDisk(data)) {
continue; // this should be added in burn plugin.
} else {
QAction *act = menuSendTo->addAction(label);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,22 +179,18 @@ bool BlockEntryFileEntity::showUsageSize() const
AbstractEntryFileEntity::EntryOrder BlockEntryFileEntity::order() const
{
// NOTE(xust): removable/hintSystem is not always correct in some certain hardwares.
if (datas.value(DeviceProperty::kMountPoint).toString() == "/")
return AbstractEntryFileEntity::EntryOrder::kOrderSysDiskRoot;
auto clearInfo = datas.value(BlockAdditionalProperty::kClearBlockProperty, QVariantHash()).toHash();
if (clearInfo.value(DeviceProperty::kMountPoint, "").toString() == "/")
if (DeviceUtils::isSystemDisk(clearInfo.isEmpty() ? datas : clearInfo))
return AbstractEntryFileEntity::EntryOrder::kOrderSysDiskRoot;

bool canPowerOff = datas.value(DeviceProperty::kCanPowerOff).toBool();
if (!canPowerOff && datas.value(DeviceProperty::kIdLabel).toString().startsWith("_dde_data"))
return AbstractEntryFileEntity::EntryOrder::kOrderSysDiskData;
if (!canPowerOff && clearInfo.value(DeviceProperty::kIdLabel, "").toString() == "_dde_data")
if (DeviceUtils::isDataDisk(clearInfo.isEmpty() ? datas : clearInfo))
return AbstractEntryFileEntity::EntryOrder::kOrderSysDiskData;

if (datas.value(DeviceProperty::kOptical).toBool()
|| datas.value(DeviceProperty::kOpticalDrive).toBool())
return AbstractEntryFileEntity::EntryOrder::kOrderOptical;

bool canPowerOff = datas.value(DeviceProperty::kCanPowerOff).toBool();
if (canPowerOff && !isSiblingOfRoot())
return AbstractEntryFileEntity::EntryOrder::kOrderRemovableDisks;

Expand Down Expand Up @@ -275,12 +271,16 @@ QUrl BlockEntryFileEntity::mountPoint() const
{
auto mptList = getProperty(DeviceProperty::kMountPoints).toStringList();
QUrl target;

if (mptList.isEmpty())
return target;

if (DeviceUtils::isSystemDisk(datas))
return QUrl::fromLocalFile(QDir::rootPath());

// when enter DataDisk, enter Home directory.
for (const auto &mpt : mptList) {
if (mpt != QDir::rootPath()) {
if (DeviceUtils::isDataDisk(datas)) {
const QString &userHome = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
const QString &homeBindPath = FileUtils::bindPathTransform(userHome, true);
if (userHome != homeBindPath && homeBindPath.startsWith(mpt))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ QVariantMap ComputerItemWatcher::makeSidebarItem(DFMEntryFileInfoPointer info)
if (info->extraProperty(DeviceProperty::kIsLoopDevice).toBool()) {
visableKey = kItemVisiableControlKeys[1];
visableName = kItemVisiableControlNames[1];
} else if (DeviceUtils::isSystemDisk(info->extraProperties())) {
} else if (DeviceUtils::isBuiltInDisk(info->extraProperties())) {
visableKey = kItemVisiableControlKeys[0];
visableName = kItemVisiableControlNames[0];
reportName = info->targetUrl().path() == "/" ? "System Disk" : "Data Disk";
Expand Down

0 comments on commit 3f0d013

Please sign in to comment.