Compare commits
1 commit
master
...
fix_copy_a
Author | SHA1 | Date | |
---|---|---|---|
|
caaac80ca5 |
5 changed files with 136 additions and 1 deletions
|
@ -5,8 +5,9 @@ target_link_libraries(kdeconnect_notifications
|
|||
kdeconnectcore
|
||||
Qt::DBus
|
||||
Qt::Widgets
|
||||
KF6::Notifications
|
||||
KF6::GuiAddons
|
||||
KF6::I18n
|
||||
KF6::Notifications
|
||||
KF6::WindowSystem
|
||||
)
|
||||
|
||||
|
|
|
@ -11,11 +11,15 @@
|
|||
#include <dbushelper.h>
|
||||
|
||||
#include <KPluginFactory>
|
||||
#include <KSystemClipboard>
|
||||
|
||||
#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
|
||||
#include <KStartupInfo>
|
||||
#include <private/qtx11extras_p.h>
|
||||
#endif
|
||||
|
||||
#include <QMimeData>
|
||||
|
||||
K_PLUGIN_CLASS_WITH_JSON(NotificationsPlugin, "kdeconnect_notifications.json")
|
||||
|
||||
void NotificationsPlugin::connected()
|
||||
|
@ -175,6 +179,32 @@ void NotificationsPlugin::sendAction(const QString &key, const QString &action)
|
|||
np.set<QString>(QStringLiteral("key"), key);
|
||||
np.set<QString>(QStringLiteral("action"), action);
|
||||
sendPacket(np);
|
||||
|
||||
copyAuthCodeIfPresent(action);
|
||||
}
|
||||
|
||||
void NotificationsPlugin::copyAuthCodeIfPresent(const QString &action)
|
||||
{
|
||||
// The auth code we receive has invisible characters in it for some reason.
|
||||
// (U+2063 INVISIBLE SEPARATOR between each digit).
|
||||
// Remove them if present before continuing.
|
||||
QString sanitizedAction = action;
|
||||
sanitizedAction.remove(QChar(0x2063));
|
||||
|
||||
// Match blocks of digits, 4-10 digits long. This should match auth codes
|
||||
// in any language without relying on the action text having a specific
|
||||
// keyword in it such as "Copy" in English.
|
||||
QRegularExpression authCodeRegex(QStringLiteral("\\b(\\d{4,10})\\b"));
|
||||
QRegularExpressionMatch match = authCodeRegex.match(sanitizedAction);
|
||||
|
||||
if (!match.hasMatch()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString text = match.captured(1);
|
||||
auto mimeData = new QMimeData;
|
||||
mimeData->setText(text);
|
||||
KSystemClipboard::instance()->setMimeData(mimeData, QClipboard::Clipboard);
|
||||
}
|
||||
|
||||
QString NotificationsPlugin::newId()
|
||||
|
|
|
@ -43,6 +43,14 @@ Q_SIGNALS:
|
|||
Q_SCRIPTABLE void allNotificationsRemoved();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Check if the action is to copy an auth code, if so add the code to the desktop clipboard.
|
||||
*
|
||||
* This is necessary since access to the Android clipboard has become more restricted for apps
|
||||
* that are not the foreground app since Android 10.
|
||||
*/
|
||||
void copyAuthCodeIfPresent(const QString &action);
|
||||
|
||||
void removeNotification(const QString &internalId);
|
||||
QString newId(); // Generates successive identifiers to use as public ids
|
||||
void notificationReady();
|
||||
|
|
|
@ -5,8 +5,10 @@ set(kdeconnect_libraries
|
|||
kdeconnectinterfaces
|
||||
kdeconnectsmshelper
|
||||
kdeconnectversion
|
||||
KF6::GuiAddons
|
||||
KF6::I18n
|
||||
KF6::KIOWidgets
|
||||
KF6::Notifications
|
||||
Qt::DBus
|
||||
Qt::Network
|
||||
KF6::People
|
||||
|
@ -14,6 +16,7 @@ set(kdeconnect_libraries
|
|||
Qt::Test
|
||||
)
|
||||
|
||||
ecm_add_test(notificationstest.cpp LINK_LIBRARIES ${kdeconnect_libraries})
|
||||
ecm_add_test(pluginloadtest.cpp LINK_LIBRARIES ${kdeconnect_libraries})
|
||||
ecm_add_test(sendfiletest.cpp LINK_LIBRARIES ${kdeconnect_libraries})
|
||||
ecm_add_test(smshelpertest.cpp LINK_LIBRARIES ${kdeconnect_libraries})
|
||||
|
|
93
tests/notificationstest.cpp
Normal file
93
tests/notificationstest.cpp
Normal file
|
@ -0,0 +1,93 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Kristen McWilliam <kmcwilliampublic@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
*/
|
||||
|
||||
#include "kdeconnectplugin.h"
|
||||
#include "testdaemon.h"
|
||||
|
||||
#include <KSystemClipboard>
|
||||
|
||||
#include <QtTest>
|
||||
|
||||
/**
|
||||
* Test the NotificationsPlugin class
|
||||
*/
|
||||
class NotificationsPluginTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
NotificationsPluginTest()
|
||||
{
|
||||
QStandardPaths::setTestModeEnabled(true);
|
||||
m_daemon = new TestDaemon;
|
||||
}
|
||||
|
||||
private:
|
||||
TestDaemon *m_daemon;
|
||||
|
||||
private Q_SLOTS:
|
||||
|
||||
/**
|
||||
* If the user selects the action to copy an auth code, the auth code should
|
||||
* be copied to the desktop clipboard.
|
||||
*/
|
||||
void testAuthCodeIsCopied()
|
||||
{
|
||||
Device *device = nullptr;
|
||||
const QList<Device *> devicesList = m_daemon->devicesList();
|
||||
|
||||
for (Device *id : devicesList) {
|
||||
if (id->isReachable()) {
|
||||
if (!id->isPaired())
|
||||
id->requestPairing();
|
||||
device = id;
|
||||
}
|
||||
}
|
||||
|
||||
if (device == nullptr) {
|
||||
QFAIL("Unable to determine device");
|
||||
}
|
||||
|
||||
QCOMPARE(device->isReachable(), true);
|
||||
QCOMPARE(device->isPaired(), true);
|
||||
|
||||
KdeConnectPlugin *plugin = device->plugin(QStringLiteral("kdeconnect_notifications"));
|
||||
QVERIFY(plugin);
|
||||
|
||||
const QString key = QStringLiteral("0|com.google.android.apps.messaging|2|com.google.android.apps.messaging:incoming_message:23|10129");
|
||||
|
||||
// Note that the auth code we receive to work with has invisible
|
||||
// characters in it for some reason. (U+2063 INVISIBLE SEPARATOR between
|
||||
// each digit)
|
||||
//
|
||||
// `action` here is equal to `Copy \"671733\"`, but with the invisible
|
||||
// characters written out explicitly to make it easier to read, and to
|
||||
// prevent confusion when reading the test code.
|
||||
const QString action = QStringLiteral("Copy \"6\u20637\u20631\u20637\u20633\u20633\"");
|
||||
|
||||
const QString expectedClipboardContents = QStringLiteral("671733");
|
||||
|
||||
// Verify that the clipboard does not contain the auth code already
|
||||
const QString originalClipboardContents = KSystemClipboard::instance()->text(QClipboard::Clipboard);
|
||||
QVERIFY(originalClipboardContents != expectedClipboardContents);
|
||||
|
||||
// Send the action
|
||||
plugin->metaObject()->invokeMethod(plugin, "sendAction", Q_ARG(QString, key), Q_ARG(QString, action));
|
||||
|
||||
// Verify that the clipboard now contains the auth code
|
||||
const QString updatedClipboardContents = KSystemClipboard::instance()->text(QClipboard::Clipboard);
|
||||
QCOMPARE(updatedClipboardContents, expectedClipboardContents);
|
||||
|
||||
// Set the clipboard back to its original state
|
||||
auto mimeData = new QMimeData;
|
||||
mimeData->setText(originalClipboardContents);
|
||||
KSystemClipboard::instance()->setMimeData(mimeData, QClipboard::Clipboard);
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(NotificationsPluginTest);
|
||||
|
||||
#include "notificationstest.moc"
|
Loading…
Reference in a new issue