File indexing completed on 2024-04-21 05:32:52
0001 /* 0002 SPDX-FileCopyrightText: 2018 David Edmundson <davidedmundson@kde.org> 0003 SPDX-FileCopyrightText: 2018 Eike Hein <hein@kde.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "browserintegrationreminder.h" 0009 0010 #include <QAction> 0011 #include <QDBusConnection> 0012 #include <QDBusConnectionInterface> 0013 #include <QDBusMessage> 0014 #include <QDBusServiceWatcher> 0015 #include <QDebug> 0016 #include <QDesktopServices> 0017 #include <QMenu> 0018 #include <QTimer> 0019 0020 #include <PlasmaActivities/ResourceInstance> 0021 #include <KConfig> 0022 #include <KConfigGroup> 0023 #include <KIO/ApplicationLauncherJob> 0024 #include <KLocalizedString> 0025 #include <KNotificationJobUiDelegate> 0026 #include <KService> 0027 #include <KSharedConfig> 0028 #include <KStatusNotifierItem> 0029 #include <kpluginfactory.h> 0030 0031 K_PLUGIN_FACTORY_WITH_JSON(BrowserIntegrationReminderFactory, "browserintegrationreminder.json", registerPlugin<BrowserIntegrationReminder>();) 0032 0033 static const QString s_dbusServiceName = QStringLiteral("org.kde.plasma.browser_integration"); 0034 0035 #define MAX_SHOW_COUNT 3 0036 0037 BrowserIntegrationReminder::BrowserIntegrationReminder(QObject *parent, const QList<QVariant> &) 0038 : KDEDModule(parent) 0039 { 0040 m_debug = qEnvironmentVariableIsSet("PLASMA_BROWSE_REMIND_FORCE"); 0041 auto config = KSharedConfig::openConfig()->group(QStringLiteral("PlasmaBrowserIntegration")); 0042 m_shownCount = config.readEntry("shownCount", 0); 0043 0044 if (m_shownCount > MAX_SHOW_COUNT && !m_debug) { 0045 disableAutoload(); // safer than it looks it won't be processed till we hit the event loop 0046 return; 0047 } 0048 0049 QUrl firefox(QStringLiteral("https://addons.mozilla.org/en-US/firefox/addon/plasma-integration/")); 0050 m_browsers[QStringLiteral("firefox.desktop")] = firefox; 0051 m_browsers[QStringLiteral("nightly.desktop")] = firefox; 0052 m_browsers[QStringLiteral("librewolf.desktop")] = firefox; 0053 0054 QUrl chrome(QStringLiteral("https://chrome.google.com/webstore/detail/plasma-integration/cimiefiiaegbelhefglklhhakcgmhkai")); 0055 m_browsers[QStringLiteral("google-chrome.desktop")] = chrome; 0056 m_browsers[QStringLiteral("google-chrome-beta.desktop")] = chrome; 0057 m_browsers[QStringLiteral("google-chrome-unstable.desktop")] = chrome; 0058 m_browsers[QStringLiteral("chromium-browser.desktop")] = chrome; 0059 m_browsers[QStringLiteral("vivaldi-stable.desktop")] = chrome; 0060 m_browsers[QStringLiteral("brave-browser.desktop")] = chrome; 0061 0062 QUrl edge(QStringLiteral("https://microsoftedge.microsoft.com/addons/detail/plasma-integration/dnnckbejblnejeabhcmhklcaljjpdjeh")); 0063 m_browsers[QStringLiteral("microsoft-edge.desktop")] = edge; 0064 m_browsers[QStringLiteral("microsoft-edge-beta.desktop")] = edge; 0065 m_browsers[QStringLiteral("microsoft-edge-dev.desktop")] = edge; 0066 0067 setModuleName(QStringLiteral("BrowserIntegrationReminder")); 0068 QDBusConnection dbus = QDBusConnection::sessionBus(); 0069 dbus.connect(QStringLiteral("org.kde.ActivityManager"), 0070 QStringLiteral("/ActivityManager/Resources/Scoring"), 0071 QStringLiteral("org.kde.ActivityManager.ResourcesScoring"), 0072 QStringLiteral("ResourceScoreUpdated"), 0073 this, 0074 SLOT(onResourceScoresChanged(QString, QString, QString, double, unsigned int, unsigned int))); 0075 } 0076 0077 BrowserIntegrationReminder::~BrowserIntegrationReminder() 0078 { 0079 } 0080 0081 void BrowserIntegrationReminder::onResourceScoresChanged(const QString &activity, 0082 const QString &client, 0083 const QString &resource, 0084 double score, 0085 unsigned int lastUpdate, 0086 unsigned int firstUpdate) 0087 { 0088 Q_UNUSED(activity); 0089 Q_UNUSED(score); 0090 Q_UNUSED(lastUpdate); 0091 Q_UNUSED(firstUpdate); 0092 Q_UNUSED(client) 0093 0094 if (!resource.startsWith(QStringLiteral("applications:"))) { 0095 return; 0096 } 0097 const QString desktopFile = resource.mid(strlen("applications:")); 0098 if (!m_browsers.contains(desktopFile)) { 0099 return; 0100 } 0101 // wait a few seconds and then query if the extension is active 0102 QTimer::singleShot(10 * 1000, this, [this, desktopFile]() { 0103 onBrowserStarted(desktopFile); 0104 }); 0105 } 0106 0107 void BrowserIntegrationReminder::onBrowserStarted(const QString &browser) 0108 { 0109 QDBusConnection bus = QDBusConnection::sessionBus(); 0110 if (m_sni) { 0111 return; 0112 } 0113 0114 if (!KService::serviceByStorageId(browser)) { 0115 return; 0116 } 0117 0118 if (!m_watcher) { 0119 m_watcher = new QDBusServiceWatcher(s_dbusServiceName, bus, QDBusServiceWatcher::WatchForRegistration, this); 0120 connect(m_watcher, &QDBusServiceWatcher::serviceRegistered, this, [this](const QString &service) { 0121 Q_UNUSED(service); 0122 if (m_sni) { 0123 m_sni->deleteLater(); 0124 disableAutoload(); 0125 } 0126 }); 0127 } 0128 0129 if (!m_debug && bus.interface()->isServiceRegistered(s_dbusServiceName)) { 0130 // the user has the extension installed, we don't need to keep checking 0131 // env var exists for easier testing 0132 disableAutoload(); 0133 return; 0134 } 0135 0136 m_sni = new KStatusNotifierItem(this); 0137 m_shownCount++; 0138 auto config = KSharedConfig::openConfig()->group(QStringLiteral("PlasmaBrowserIntegration")); 0139 config.writeEntry("shownCount", m_shownCount); 0140 0141 m_sni->setTitle(i18n("Get Plasma Browser Integration")); 0142 m_sni->setIconByName(QStringLiteral("plasma-browser-integration")); 0143 m_sni->setStandardActionsEnabled(false); 0144 m_sni->setStatus(KStatusNotifierItem::Active); 0145 0146 connect(m_sni, &KStatusNotifierItem::activateRequested, this, [this, browser]() { 0147 const KService::Ptr service = KService::serviceByStorageId(browser); 0148 0149 if (!service) { 0150 unload(); 0151 return; 0152 } 0153 0154 KIO::ApplicationLauncherJob *job = new KIO::ApplicationLauncherJob(service); 0155 job->setUrls({m_browsers[browser]}); 0156 job->setUiDelegate(new KNotificationJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled)); 0157 job->start(); 0158 0159 KActivities::ResourceInstance::notifyAccessed(QUrl(QStringLiteral("applications:") + browser), 0160 QStringLiteral("org.kde.plasma.browserintegrationreminder")); 0161 // remove for this session. 0162 // If the user installed it successfully we won't show anything next session 0163 // If they didn't they'll get the link next login 0164 unload(); 0165 }); 0166 0167 auto *menu = new QMenu; 0168 auto *action = new QAction(QIcon::fromTheme(QStringLiteral("view-hidden")), i18n("Do not show again")); 0169 menu->addAction(action); 0170 connect(action, &QAction::triggered, this, [this]() { 0171 auto config = KSharedConfig::openConfig()->group(QStringLiteral("PlasmaBrowserIntegration")); 0172 config.writeEntry("shownCount", 100); 0173 disableAutoload(); 0174 }); 0175 0176 m_sni->setContextMenu(menu); 0177 } 0178 0179 void BrowserIntegrationReminder::unload() 0180 { 0181 QDBusConnection dbus = QDBusConnection::sessionBus(); 0182 QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kded6"), 0183 QStringLiteral("/kded"), 0184 QStringLiteral("org.kde.kded6"), 0185 QStringLiteral("unloadModule")); 0186 msg.setArguments({QVariant(QStringLiteral("browserintegrationreminder"))}); 0187 dbus.call(msg, QDBus::NoBlock); 0188 } 0189 0190 void BrowserIntegrationReminder::disableAutoload() 0191 { 0192 QDBusConnection dbus = QDBusConnection::sessionBus(); 0193 QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kded6"), 0194 QStringLiteral("/kded"), 0195 QStringLiteral("org.kde.kded6"), 0196 QStringLiteral("setModuleAutoloading")); 0197 msg.setArguments({QVariant(QStringLiteral("browserintegrationreminder")), QVariant(false)}); 0198 dbus.call(msg, QDBus::NoBlock); 0199 unload(); 0200 } 0201 0202 #include "browserintegrationreminder.moc" 0203 0204 #include "moc_browserintegrationreminder.cpp"