File indexing completed on 2024-05-12 15:55:34

0001 // SPDX-FileCopyrightText: 2021 Johannes Zarl-Zierl <johannes@zarl-zierl.at>
0002 // SPDX-FileCopyrightText: 2022 Johannes Zarl-Zierl <johannes@zarl-zierl.at>
0003 //
0004 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 
0006 #include "CrashSentinel.h"
0007 #include "Logging.h"
0008 
0009 #include <KConfigGroup>
0010 #include <KSharedConfig>
0011 #include <QLoggingCategory>
0012 
0013 namespace
0014 {
0015 constexpr auto CFG_GROUP { "CrashInfo" };
0016 constexpr auto CFG_HISTORY { "_crashHistory" };
0017 constexpr auto CFG_DISABLED { "_disabled" };
0018 }
0019 
0020 KPABase::CrashSentinel::CrashSentinel(const QString &component, const QByteArray &crashInfo)
0021     : m_component(component)
0022     , m_crashInfo(crashInfo)
0023 {
0024     auto cfgGroup = KSharedConfig::openConfig()->group(CFG_GROUP);
0025     m_lastCrashInfo = cfgGroup.readEntry(m_component, QByteArray());
0026     if (!m_lastCrashInfo.isEmpty()) {
0027         const auto historyEntry = m_component + QString::fromUtf8(CFG_HISTORY);
0028         auto history = cfgGroup.readEntry(historyEntry, QList<QByteArray>());
0029         history.append(m_lastCrashInfo);
0030         cfgGroup.writeEntry(historyEntry, history);
0031     }
0032     qCDebug(BaseLog).nospace() << "Created CrashSentinel for component " << m_component << ". Previous crash information: "
0033                                << m_lastCrashInfo << (isDisabled() ? "; crash detection was permanently disabled." : "; crash detection is active.");
0034 }
0035 
0036 KPABase::CrashSentinel::~CrashSentinel()
0037 {
0038     suspend();
0039 }
0040 
0041 bool KPABase::CrashSentinel::hasCrashInfo() const
0042 {
0043     if (isDisabled())
0044         return false;
0045     return !m_lastCrashInfo.isEmpty();
0046 }
0047 
0048 QByteArray KPABase::CrashSentinel::lastCrashInfo() const
0049 {
0050     if (isDisabled())
0051         return {};
0052     return m_lastCrashInfo;
0053 }
0054 
0055 QList<QByteArray> KPABase::CrashSentinel::crashHistory() const
0056 {
0057     if (isDisabled())
0058         return {};
0059     const auto cfgGroup = KSharedConfig::openConfig()->group(CFG_GROUP);
0060     return cfgGroup.readEntry(m_component + QString::fromUtf8(CFG_HISTORY), QList<QByteArray>());
0061 }
0062 
0063 void KPABase::CrashSentinel::clearCrashHistory()
0064 {
0065     auto cfgGroup = KSharedConfig::openConfig()->group(CFG_GROUP);
0066     cfgGroup.deleteEntry(m_component + QString::fromUtf8(CFG_HISTORY));
0067     cfgGroup.deleteEntry(m_component + QString::fromUtf8(CFG_DISABLED));
0068 }
0069 
0070 void KPABase::CrashSentinel::setCrashInfo(const QByteArray &crashInfo)
0071 {
0072     const bool wasActive = !isSuspended();
0073     suspend();
0074     m_crashInfo = crashInfo;
0075     if (wasActive) {
0076         activate();
0077     }
0078 }
0079 
0080 QString KPABase::CrashSentinel::component() const
0081 {
0082     return m_component;
0083 }
0084 
0085 QByteArray KPABase::CrashSentinel::crashInfo() const
0086 {
0087     return m_crashInfo;
0088 }
0089 
0090 bool KPABase::CrashSentinel::isSuspended() const
0091 {
0092     const auto cfgGroup = KSharedConfig::openConfig()->group(CFG_GROUP);
0093     return !cfgGroup.hasKey(m_component);
0094 }
0095 
0096 void KPABase::CrashSentinel::suspend()
0097 {
0098     auto cfgGroup = KSharedConfig::openConfig()->group(CFG_GROUP);
0099     cfgGroup.deleteEntry(m_component);
0100     cfgGroup.sync();
0101     qCDebug(BaseLog) << "CrashSentinel for component" << m_component << "suspended.";
0102 }
0103 
0104 void KPABase::CrashSentinel::activate()
0105 {
0106     auto cfgGroup = KSharedConfig::openConfig()->group(CFG_GROUP);
0107     cfgGroup.writeEntry(m_component, m_crashInfo);
0108     cfgGroup.sync();
0109     qCDebug(BaseLog) << "CrashSentinel for component" << m_component << "activated. Crash info:" << m_crashInfo;
0110 }
0111 
0112 void KPABase::CrashSentinel::disablePermanently()
0113 {
0114     auto cfgGroup = KSharedConfig::openConfig()->group(CFG_GROUP);
0115     cfgGroup.writeEntry(m_component + QString::fromUtf8(CFG_DISABLED), true);
0116     cfgGroup.sync();
0117     qCDebug(BaseLog) << "CrashSentinel for component" << m_component << "permanently disabled.";
0118 }
0119 
0120 bool KPABase::CrashSentinel::isDisabled() const
0121 {
0122     auto cfgGroup = KSharedConfig::openConfig()->group(CFG_GROUP);
0123     return cfgGroup.readEntry(m_component + QString::fromUtf8(CFG_DISABLED), false);
0124 }
0125 
0126 // vi:expandtab:tabstop=4 shiftwidth=4: